Upgrade to FreeType 2.7.1.

BUG=pdfium:601

Change-Id: I07756cd208cd2221802ff2d331f316b6618a41e0
Reviewed-on: https://pdfium-review.googlesource.com/3120
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 175106a..530c760 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -908,6 +908,8 @@
     ":fxcrt",
   ]
 
+  defines = [ "DEFINE_PS_TABLES" ]
+
   if (pdf_enable_xfa) {
     sources += [
       "core/fxge/cfx_unicodeencodingex.h",
diff --git a/DEPS b/DEPS
index 26f8c8e..83917d3 100644
--- a/DEPS
+++ b/DEPS
@@ -15,7 +15,7 @@
   'gtest_revision': '8245545b6dc9c4703e6496d1efd19e975ad2b038',
   'icu_revision': '73e24736676b4b438270fda44e5b2c83b49fdd80',
   'instrumented_lib_revision': '61065eb0db191f46bdea202e833f5cd1f1ecedcd',
-  'pdfium_tests_revision': 'd25a422ab03d6c3109370bc454c629575e969329',
+  'pdfium_tests_revision': '46cec65c6895ed37a9bf960ce341a5655c7519bf',
   'skia_revision': '90e3cd78991ef337dbd0023efb30ece864694308',
   'tools_memory_revision': '427f10475e1a8d72424c29d00bf689122b738e5d',
   'trace_event_revision': '06294c8a4a6f744ef284cd63cfe54dbf61eea290',
diff --git a/core/fpdfapi/parser/fpdf_parser_decode_embeddertest.cpp b/core/fpdfapi/parser/fpdf_parser_decode_embeddertest.cpp
index b1acd16..136d7c9 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode_embeddertest.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode_embeddertest.cpp
@@ -116,8 +116,10 @@
   FPDF_BITMAP bitmap = RenderPage(page);
 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   const char kExpectedMd5sum[] = "b90475ca64d1348c3bf5e2b77ad9187a";
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+  const char kExpectedMd5sum[] = "5db84ceda153acc4420c2062b182191b";
 #else
-  const char kExpectedMd5sum[] = "6f9f0fd903da177babb24dd50a806a56";
+  const char kExpectedMd5sum[] = "f24438fe53948941200fd43da37908bc";
 #endif
   CompareBitmap(bitmap, 200, 200, kExpectedMd5sum);
   FPDFBitmap_Destroy(bitmap);
diff --git a/fpdfsdk/fpdfedit_embeddertest.cpp b/fpdfsdk/fpdfedit_embeddertest.cpp
index 46eab09..a54a9b9 100644
--- a/fpdfsdk/fpdfedit_embeddertest.cpp
+++ b/fpdfsdk/fpdfedit_embeddertest.cpp
@@ -366,7 +366,7 @@
 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   const char md5[] = "f9e6fa74230f234286bfcada9f7606d8";
 #else
-  const char md5[] = "17c942c76ff229200f2c98073bb60d85";
+  const char md5[] = "2fdfc5dda29374cfba4349362e38ebdb";
 #endif
   CompareBitmap(bitmap, 200, 200, md5);
   FPDFBitmap_Destroy(bitmap);
@@ -437,7 +437,7 @@
 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   const char md5[] = "a4dddc1a3930fa694bbff9789dab4161";
 #else
-  const char md5[] = "7c3a36ba7cec01688a16a14bfed9ecfc";
+  const char md5[] = "6e8a9b0682f60fd3ff1bf087b093d30d";
 #endif
   CompareBitmap(page_bitmap, 612, 792, md5);
   FPDFBitmap_Destroy(page_bitmap);
@@ -453,8 +453,10 @@
   page_bitmap = RenderPage(page);
 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   const char md5_2[] = "a5c4ace4c6f27644094813fe1441a21c";
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+  const char md5_2[] = "56863642d4d8b418cfd810fdb5a5d92f";
 #else
-  const char md5_2[] = "e0e0873e3a2634a6394a431a51ce90ff";
+  const char md5_2[] = "0c83875429688bda45a55a692d5aa781";
 #endif
   CompareBitmap(page_bitmap, 612, 792, md5_2);
   FPDFBitmap_Destroy(page_bitmap);
@@ -470,8 +472,10 @@
   page_bitmap = RenderPage(page);
 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   const char md5_3[] = "40b3ef04f915ff4c4208948001763544";
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+  const char md5_3[] = "174f30c36c73adb265c0f6ddb3a61c87";
 #else
-  const char md5_3[] = "903ee10b6a9f0be51ecad0a1a0eeb171";
+  const char md5_3[] = "abfa9246d60f821b5b7638efd32dfd92";
 #endif
   CompareBitmap(page_bitmap, 612, 792, md5_3);
   FPDFBitmap_Destroy(page_bitmap);
diff --git a/testing/resources/pixel/bug_524043_1_expected.pdf.0.png b/testing/resources/pixel/bug_524043_1_expected.pdf.0.png
index a044bb0..5a46384 100644
--- a/testing/resources/pixel/bug_524043_1_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_524043_1_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_2_expected.pdf.0.png b/testing/resources/pixel/bug_524043_2_expected.pdf.0.png
index 19de52a..34aa9b4 100644
--- a/testing/resources/pixel/bug_524043_2_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_524043_2_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_3_expected.pdf.0.png b/testing/resources/pixel/bug_524043_3_expected.pdf.0.png
index a044bb0..5a46384 100644
--- a/testing/resources/pixel/bug_524043_3_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_524043_3_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_4_expected.pdf.0.png b/testing/resources/pixel/bug_524043_4_expected.pdf.0.png
index a044bb0..5a46384 100644
--- a/testing/resources/pixel/bug_524043_4_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_524043_4_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_5_expected.pdf.0.png b/testing/resources/pixel/bug_524043_5_expected.pdf.0.png
index a044bb0..5a46384 100644
--- a/testing/resources/pixel/bug_524043_5_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_524043_5_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_524043_7_expected.pdf.0.png b/testing/resources/pixel/bug_524043_7_expected.pdf.0.png
index 19de52a..34aa9b4 100644
--- a/testing/resources/pixel/bug_524043_7_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_524043_7_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_543018_1_expected.pdf.0.png b/testing/resources/pixel/bug_543018_1_expected.pdf.0.png
index a044bb0..5a46384 100644
--- a/testing/resources/pixel/bug_543018_1_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_543018_1_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_543018_2_expected.pdf.0.png b/testing/resources/pixel/bug_543018_2_expected.pdf.0.png
index a044bb0..5a46384 100644
--- a/testing/resources/pixel/bug_543018_2_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_543018_2_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/bug_551258_1_expected.pdf.0.png b/testing/resources/pixel/bug_551258_1_expected.pdf.0.png
index a044bb0..5a46384 100644
--- a/testing/resources/pixel/bug_551258_1_expected.pdf.0.png
+++ b/testing/resources/pixel/bug_551258_1_expected.pdf.0.png
Binary files differ
diff --git a/testing/resources/pixel/font_size_expected.pdf.0.png b/testing/resources/pixel/font_size_expected.pdf.0.png
index a14df36..5950b74 100644
--- a/testing/resources/pixel/font_size_expected.pdf.0.png
+++ b/testing/resources/pixel/font_size_expected.pdf.0.png
Binary files differ
diff --git a/third_party/BUILD.gn b/third_party/BUILD.gn
index 78afcd0..2055821 100644
--- a/third_party/BUILD.gn
+++ b/third_party/BUILD.gn
@@ -43,7 +43,12 @@
   if (is_clang) {
     # open_face_PS_from_sfnt_stream() and open_face_from_buffer() in
     # ftbase.h are unused.
-    cflags = [ "-Wno-unused-function" ]
+    #
+    # ttgload.c casts from unsigned int to unsigned long to void*.
+    cflags = [
+        "-Wno-unused-function",
+        "-Wno-int-to-void-pointer-cast",
+    ]
   }
 }
 
@@ -96,6 +101,7 @@
     "freetype/include/freetype/internal/ftdebug.h",
     "freetype/include/freetype/internal/ftdriver.h",
     "freetype/include/freetype/internal/ftgloadr.h",
+    "freetype/include/freetype/internal/fthash.h",
     "freetype/include/freetype/internal/ftmemory.h",
     "freetype/include/freetype/internal/ftobjs.h",
     "freetype/include/freetype/internal/ftpic.h",
@@ -110,6 +116,7 @@
     "freetype/include/freetype/internal/services/svfntfmt.h",
     "freetype/include/freetype/internal/services/svgldict.h",
     "freetype/include/freetype/internal/services/svkern.h",
+    "freetype/include/freetype/internal/services/svmetric.h",
     "freetype/include/freetype/internal/services/svmm.h",
     "freetype/include/freetype/internal/services/svpostnm.h",
     "freetype/include/freetype/internal/services/svprop.h",
diff --git a/third_party/freetype/0000-include.patch b/third_party/freetype/0000-include.patch
index d7478e7..d6c8374 100644
--- a/third_party/freetype/0000-include.patch
+++ b/third_party/freetype/0000-include.patch
@@ -1,28 +1,6 @@
-diff -ru freetype-2.6.1/include/freetype/config/ftmodule.h include/freetype/config/ftmodule.h
---- freetype-2.6.1/include/freetype/config/ftmodule.h	2015-11-05 13:52:36.734733186 -0800
-+++ include/freetype/config/ftmodule.h	2015-11-05 13:44:54.445479822 -0800
-@@ -1,3 +1,20 @@
-+/***************************************************************************/
-+/*                                                                         */
-+/*  ftmodule.h                                                             */
-+/*                                                                         */
-+/*    FreeType modules public interface (specification).                   */
-+/*                                                                         */
-+/*  Copyright 1996-2001, 2002, 2003 by                                     */
-+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-+/*                                                                         */
-+/*  This file is part of the FreeType project, and may only be used,       */
-+/*  modified, and distributed under the terms of the FreeType project      */
-+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-+/*  this file you indicate that you have read the license and              */
-+/*  understand and accept it fully.                                        */
-+/*                                                                         */
-+/***************************************************************************/
-+
- /*
-  *  This file registers the FreeType modules compiled into the library.
-  *
-@@ -10,15 +27,15 @@
+--- third_party/freetype/include/freetype/config/ftmodule.h	2017-03-07 20:15:52.781636524 -0800
++++ third_party/freetype/include/freetype/config/ftmodule.h	2017-03-22 22:57:58.536233071 -0700
+@@ -10,15 +10,15 @@
   *
   */
  
@@ -43,7 +21,7 @@
  FT_USE_MODULE( FT_Module_Class, psaux_module_class )
  FT_USE_MODULE( FT_Module_Class, psnames_module_class )
  FT_USE_MODULE( FT_Module_Class, pshinter_module_class )
-@@ -27,6 +44,6 @@
+@@ -27,6 +27,6 @@
  FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
  FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class )
  FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class )
@@ -51,10 +29,9 @@
 +//FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )
  
  /* EOF */
-diff -ru freetype-2.6.1/include/freetype/config/ftoption.h include/freetype/config/ftoption.h
---- freetype-2.6.1/include/freetype/config/ftoption.h	2015-11-05 13:52:36.734733186 -0800
-+++ include/freetype/config/ftoption.h	2015-11-05 13:44:54.445479822 -0800
-@@ -92,7 +92,7 @@
+--- third_party/freetype/include/freetype/config/ftoption.h	2017-03-07 20:15:52.781636524 -0800
++++ third_party/freetype/include/freetype/config/ftoption.h	2017-03-22 22:57:58.532233095 -0700
+@@ -122,7 +122,7 @@
    /* This is done to allow FreeType clients to run unmodified, forcing     */
    /* them to display normal gray-level anti-aliased glyphs.                */
    /*                                                                       */
@@ -63,16 +40,16 @@
  
  
    /*************************************************************************/
-@@ -163,7 +163,7 @@
+@@ -193,7 +193,7 @@
    /*   Define this macro if you want to enable this `feature'.  See also   */
    /*   the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below.                       */
    /*                                                                       */
 -#define FT_CONFIG_OPTION_USE_ZLIB
-+//#define FT_CONFIG_OPTION_USE_ZLIB
++#undef FT_CONFIG_OPTION_USE_ZLIB
  
  
    /*************************************************************************/
-@@ -336,7 +336,7 @@
+@@ -366,7 +366,7 @@
    /*                                                                       */
    /*   Note that the `FOND' resource isn't checked.                        */
    /*                                                                       */
@@ -81,7 +58,7 @@
  
  
    /*************************************************************************/
-@@ -512,7 +512,7 @@
+@@ -556,7 +556,7 @@
    /* embedded bitmaps in all formats using the SFNT module (namely         */
    /* TrueType & OpenType).                                                 */
    /*                                                                       */
@@ -90,7 +67,7 @@
  
  
    /*************************************************************************/
-@@ -681,7 +681,7 @@
+@@ -705,7 +705,7 @@
    /* and avar tables).  This has many similarities to Type 1 Multiple      */
    /* Masters support.                                                      */
    /*                                                                       */
@@ -99,7 +76,7 @@
  
  
    /*************************************************************************/
-@@ -689,7 +689,7 @@
+@@ -713,7 +713,7 @@
    /* Define TT_CONFIG_OPTION_BDF if you want to include support for        */
    /* an embedded `BDF ' table within SFNT-based bitmap formats.            */
    /*                                                                       */
@@ -108,7 +85,7 @@
  
  
    /*************************************************************************/
-@@ -725,7 +725,7 @@
+@@ -767,7 +767,7 @@
    /*                                                                       */
    /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */
    /*                                                                       */
@@ -117,4 +94,3 @@
  
  
    /*************************************************************************/
-Only in freetype-2.6.1/include/freetype: ftchapters.h
diff --git a/third_party/freetype/README.pdfium b/third_party/freetype/README.pdfium
index f8fad6f..2054aab 100644
--- a/third_party/freetype/README.pdfium
+++ b/third_party/freetype/README.pdfium
@@ -1,6 +1,7 @@
 Name: FreeType
 URL: http://www.freetype.org/
-Version: 2.6.1
+Version: VER-2-7-1-updates
+Revision: 66725768cdf758cfb3f9abf03cbf5e5a77f42088
 Security Critical: yes
 License: FreeType License (FTL)
 License File: FTL.TXT
@@ -11,24 +12,3 @@
 Local Modifications:
 
 0000-include.patch: Modifications to configuration header files.
-
-include/freetype/ftchapers.h is not included.
-
-The following directories in src/ are not included from
-upstream FreeType as they are never used:
-
-autofit
-bdf
-bzip2
-cache
-gxvalid
-gzip
-Jamfile
-lzw
-otvalid
-pcf
-pfr
-tools
-type42
-winfonts
-
diff --git a/third_party/freetype/include/freetype/config/ftconfig.h b/third_party/freetype/include/freetype/config/ftconfig.h
index d4d7993..9d7f883 100644
--- a/third_party/freetype/include/freetype/config/ftconfig.h
+++ b/third_party/freetype/include/freetype/config/ftconfig.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    ANSI-specific configuration file (specification only).               */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -35,8 +35,8 @@
   /*                                                                       */
   /*************************************************************************/
 
-#ifndef __FTCONFIG_H__
-#define __FTCONFIG_H__
+#ifndef FTCONFIG_H_
+#define FTCONFIG_H_
 
 #include <ft2build.h>
 #include FT_CONFIG_OPTIONS_H
@@ -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>                                                             */
@@ -275,7 +283,13 @@
   /*                                                                       */
 #elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 )
 
-#if defined( _MSC_VER ) && _MSC_VER >= 900  /* Visual C++ (and Intel C++) */
+#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L
+
+#define FT_LONG64
+#define FT_INT64   long long int
+#define FT_UINT64  unsigned long long int
+
+#elif defined( _MSC_VER ) && _MSC_VER >= 900  /* Visual C++ (and Intel C++) */
 
   /* this compiler provides the __int64 type */
 #define FT_LONG64
@@ -309,7 +323,7 @@
 #define FT_INT64   long long int
 #define FT_UINT64  unsigned long long int
 
-#endif /* _MSC_VER */
+#endif /* __STDC_VERSION__ >= 199901L */
 
 #endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
 
@@ -332,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
@@ -461,7 +476,7 @@
 FT_END_HEADER
 
 
-#endif /* __FTCONFIG_H__ */
+#endif /* FTCONFIG_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/config/ftheader.h b/third_party/freetype/include/freetype/config/ftheader.h
index 55f833d..950d36c 100644
--- a/third_party/freetype/include/freetype/config/ftheader.h
+++ b/third_party/freetype/include/freetype/config/ftheader.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Build macros of the FreeType 2 library.                              */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -15,8 +15,8 @@
 /*                                                                         */
 /***************************************************************************/
 
-#ifndef __FT_HEADER_H__
-#define __FT_HEADER_H__
+#ifndef FTHEADER_H_
+#define FTHEADER_H_
 
 
   /*@***********************************************************************/
@@ -753,8 +753,7 @@
    *   FT_UNPATENTED_HINTING_H
    *
    * @description:
-   *   A macro used in #include statements to name the file containing the
-   *   FreeType~2 API which performs color filtering for subpixel rendering.
+   *   Deprecated.
    */
 #define FT_UNPATENTED_HINTING_H  <freetype/ttunpat.h>
 
@@ -766,7 +765,7 @@
    *
    * @description:
    *   A macro used in #include statements to name the file containing the
-   *   FreeType~2 API which performs color filtering for subpixel rendering.
+   *   FreeType~2 API which performs incremental glyph loading.
    */
 #define FT_INCREMENTAL_H  <freetype/ftincrem.h>
 
@@ -828,7 +827,7 @@
 #endif /* FT2_BUILD_LIBRARY */
 
 
-#endif /* __FT2_BUILD_H__ */
+#endif /* FTHEADER_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/config/ftmodule.h b/third_party/freetype/include/freetype/config/ftmodule.h
index fb25574..0d31ce6 100644
--- a/third_party/freetype/include/freetype/config/ftmodule.h
+++ b/third_party/freetype/include/freetype/config/ftmodule.h
@@ -1,20 +1,3 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftmodule.h                                                             */
-/*                                                                         */
-/*    FreeType modules public interface (specification).                   */
-/*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003 by                                     */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
 /*
  *  This file registers the FreeType modules compiled into the library.
  *
diff --git a/third_party/freetype/include/freetype/config/ftoption.h b/third_party/freetype/include/freetype/config/ftoption.h
index 886e64e..802beb5 100644
--- a/third_party/freetype/include/freetype/config/ftoption.h
+++ b/third_party/freetype/include/freetype/config/ftoption.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    User-selectable configuration macros (specification only).           */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTOPTION_H__
-#define __FTOPTION_H__
+#ifndef FTOPTION_H_
+#define FTOPTION_H_
 
 
 #include <ft2build.h>
@@ -77,6 +77,36 @@
 
   /*************************************************************************/
   /*                                                                       */
+  /* If you enable this configuration option, FreeType recognizes an       */
+  /* environment variable called `FREETYPE_PROPERTIES', which can be used  */
+  /* 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'),      */
+  /* TrueType (file `ftttdrv.h'), and PCF (file `ftpcfdrv.h').             */
+  /*                                                                       */
+  /* `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                            */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+
+
+  /*************************************************************************/
+  /*                                                                       */
   /* Uncomment the line below if you want to activate sub-pixel rendering  */
   /* (a.k.a. LCD rendering, or ClearType) in this build of the library.    */
   /*                                                                       */
@@ -163,7 +193,7 @@
   /*   Define this macro if you want to enable this `feature'.  See also   */
   /*   the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below.                       */
   /*                                                                       */
-//#define FT_CONFIG_OPTION_USE_ZLIB
+#undef FT_CONFIG_OPTION_USE_ZLIB
 
 
   /*************************************************************************/
@@ -492,7 +522,21 @@
   /*   code will be used.                                                  */
   /*                                                                       */
   /*   Setting this macro is needed for systems that prohibit address      */
-  /*   fixups, such as BREW.                                               */
+  /*   fixups, such as BREW.  [Note that standard compilers like gcc or    */
+  /*   clang handle PIC generation automatically; you don't have to set    */
+  /*   FT_CONFIG_OPTION_PIC, which is only necessary for very special      */
+  /*   compilers.]                                                         */
+  /*                                                                       */
+  /*   Note that FT_CONFIG_OPTION_PIC support is not available for all     */
+  /*   modules (see `modules.cfg' for a complete list).  For building with */
+  /*   FT_CONFIG_OPTION_PIC support, do the following.                     */
+  /*                                                                       */
+  /*     0. Clone the repository.                                          */
+  /*     1. Define FT_CONFIG_OPTION_PIC.                                   */
+  /*     2. Remove all subdirectories in `src' that don't have             */
+  /*        FT_CONFIG_OPTION_PIC support.                                  */
+  /*     3. Comment out the corresponding modules in `modules.cfg'.        */
+  /*     4. Compile.                                                       */
   /*                                                                       */
 /* #define FT_CONFIG_OPTION_PIC */
 
@@ -586,73 +630,53 @@
   /*************************************************************************/
   /*                                                                       */
   /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile       */
-  /* EXPERIMENTAL subpixel hinting support into the TrueType driver.  This */
-  /* replaces the native TrueType hinting mechanism when anything but      */
-  /* FT_RENDER_MODE_MONO is requested.                                     */
+  /* subpixel hinting support into the TrueType driver.  This modifies the */
+  /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is   */
+  /* requested.                                                            */
   /*                                                                       */
-  /* Enabling this causes the TrueType driver to ignore instructions under */
-  /* certain conditions.  This is done in accordance with the guide here,  */
-  /* with some minor differences:                                          */
+  /* In particular, it modifies the bytecode interpreter to interpret (or  */
+  /* not) instructions in a certain way so that all TrueType fonts look    */
+  /* like they do in a Windows ClearType (DirectWrite) environment.  See   */
+  /* [1] for a technical overview on what this means.  See `ttinterp.h'    */
+  /* for more details on the LEAN option.                                  */
   /*                                                                       */
-  /*  http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */
+  /* There are three options.                                              */
   /*                                                                       */
-  /* By undefining this, you only compile the code necessary to hint       */
-  /* TrueType glyphs with native TT hinting.                               */
+  /* 1. This option 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.                   */
   /*                                                                       */
-  /*   This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be    */
-  /*   defined.                                                            */
+  /* 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   */
+  /*    Courier.  Legacy fonts are fonts that modify vertical stems to     */
+  /*    achieve clean black-and-white bitmaps.  The new mode focuses on    */
+  /*    applying a minimal set of rules to all fonts indiscriminately so   */
+  /*    that modern and web fonts render well while legacy fonts render    */
+  /*    okay.                                                              */
   /*                                                                       */
-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-
-  /*************************************************************************/
+  /* 3. Compile both.                                                      */
   /*                                                                       */
-  /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version  */
-  /* of the TrueType bytecode interpreter is used that doesn't implement   */
-  /* any of the patented opcodes and algorithms.  The patents related to   */
-  /* TrueType hinting have expired worldwide since May 2010; this option   */
-  /* is now deprecated.                                                    */
+  /* 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.                   */
   /*                                                                       */
-  /* Note that the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored*  */
-  /* if you define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words,  */
-  /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or                */
-  /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time.    */
+  /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be      */
+  /* defined.                                                              */
   /*                                                                       */
-  /* This macro is only useful for a small number of font files (mostly    */
-  /* for Asian scripts) that require bytecode interpretation to properly   */
-  /* load glyphs.  For all other fonts, this produces unpleasant results,  */
-  /* thus the unpatented interpreter is never used to load glyphs from     */
-  /* TrueType fonts unless one of the following two options is used.       */
+  /* [1] http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */
   /*                                                                       */
-  /*   - The unpatented interpreter is explicitly activated by the user    */
-  /*     through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag         */
-  /*     when opening the FT_Face.                                         */
-  /*                                                                       */
-  /*   - FreeType detects that the FT_Face corresponds to one of the       */
-  /*     `trick' fonts (e.g., `Mingliu') it knows about.  The font engine  */
-  /*     contains a hard-coded list of font names and other matching       */
-  /*     parameters (see function `tt_face_init' in file                   */
-  /*     `src/truetype/ttobjs.c').                                         */
-  /*                                                                       */
-  /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */
-  /*                                                                       */
-  /*   {                                                                   */
-  /*     FT_Parameter  parameter;                                          */
-  /*     FT_Open_Args  open_args;                                          */
-  /*                                                                       */
-  /*                                                                       */
-  /*     parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING;                  */
-  /*                                                                       */
-  /*     open_args.flags      = FT_OPEN_PATHNAME | FT_OPEN_PARAMS;         */
-  /*     open_args.pathname   = my_font_pathname;                          */
-  /*     open_args.num_params = 1;                                         */
-  /*     open_args.params     = &parameter;                                */
-  /*                                                                       */
-  /*     error = FT_Open_Face( library, &open_args, index, &face );        */
-  /*     ...                                                               */
-  /*   }                                                                   */
-  /*                                                                       */
-/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */
+/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  1         */
+#define TT_CONFIG_OPTION_SUBPIXEL_HINTING  2
+/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  ( 1 | 2 ) */
 
 
   /*************************************************************************/
@@ -693,6 +717,24 @@
 
 
   /*************************************************************************/
+  /*                                                                       */
+  /* Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum     */
+  /* number of bytecode instructions executed for a single run of the      */
+  /* bytecode interpreter, needed to prevent infinite loops.  You don't    */
+  /* want to change this except for very special situations (e.g., making  */
+  /* a library fuzzer spend less time to handle broken fonts).             */
+  /*                                                                       */
+  /* It is not expected that this value is ever modified by a configuring  */
+  /* script; instead, it gets surrounded with #ifndef ... #endif so that   */
+  /* the value can be set as a preprocessor option on the compiler's       */
+  /* command line.                                                         */
+  /*                                                                       */
+#ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES
+#define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES  1000000L
+#endif
+
+
+  /*************************************************************************/
   /*************************************************************************/
   /****                                                                 ****/
   /****      T Y P E 1   D R I V E R    C O N F I G U R A T I O N       ****/
@@ -793,6 +835,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     ****/
   /****                                                                 ****/
   /*************************************************************************/
@@ -838,14 +907,19 @@
 
 
   /*
-   * This macro is defined if either unpatented or native TrueType
-   * hinting is requested by the definitions above.
+   * This macro is defined if native TrueType hinting is requested by the
+   * definitions above.
    */
 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 #define  TT_USE_BYTECODE_INTERPRETER
-#undef   TT_CONFIG_OPTION_UNPATENTED_HINTING
-#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING
-#define  TT_USE_BYTECODE_INTERPRETER
+
+#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1
+#define  TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+#endif
+
+#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2
+#define  TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+#endif
 #endif
 
 
@@ -880,7 +954,7 @@
 FT_END_HEADER
 
 
-#endif /* __FTOPTION_H__ */
+#endif /* FTOPTION_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/config/ftstdlib.h b/third_party/freetype/include/freetype/config/ftstdlib.h
index 4b471d4..05a4845 100644
--- a/third_party/freetype/include/freetype/config/ftstdlib.h
+++ b/third_party/freetype/include/freetype/config/ftstdlib.h
@@ -5,7 +5,7 @@
 /*    ANSI-specific library and header configuration file (specification   */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 2002-2015 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,       */
@@ -23,14 +23,13 @@
   /* FreeType normally requires.  It also defines macros to rename the     */
   /* standard functions within the FreeType source code.                   */
   /*                                                                       */
-  /* Load a file which defines __FTSTDLIB_H__ before this one to override  */
-  /* it.                                                                   */
+  /* Load a file which defines FTSTDLIB_H_ before this one to override it. */
   /*                                                                       */
   /*************************************************************************/
 
 
-#ifndef __FTSTDLIB_H__
-#define __FTSTDLIB_H__
+#ifndef FTSTDLIB_H_
+#define FTSTDLIB_H_
 
 
 #include <stddef.h>
@@ -64,6 +63,7 @@
 #define FT_INT_MAX     INT_MAX
 #define FT_INT_MIN     INT_MIN
 #define FT_UINT_MAX    UINT_MAX
+#define FT_LONG_MIN    LONG_MIN
 #define FT_LONG_MAX    LONG_MAX
 #define FT_ULONG_MAX   ULONG_MAX
 
@@ -142,7 +142,8 @@
   /**********************************************************************/
 
 
-#define ft_atol  atol
+#define ft_strtol  strtol
+#define ft_getenv  getenv
 
 
   /**********************************************************************/
@@ -168,7 +169,7 @@
 #include <stdarg.h>
 
 
-#endif /* __FTSTDLIB_H__ */
+#endif /* FTSTDLIB_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/freetype.h b/third_party/freetype/include/freetype/freetype.h
index b6247f5..b6c6032 100644
--- a/third_party/freetype/include/freetype/freetype.h
+++ b/third_party/freetype/include/freetype/freetype.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType high-level API and common types (specification only).       */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FREETYPE_H__
-#define __FREETYPE_H__
+#ifndef FREETYPE_H_
+#define FREETYPE_H_
 
 
 #ifndef FT_FREETYPE_H
@@ -141,7 +141,6 @@
   /*    FT_FACE_FLAG_GLYPH_NAMES                                           */
   /*    FT_FACE_FLAG_EXTERNAL_STREAM                                       */
   /*    FT_FACE_FLAG_HINTER                                                */
-  /*    FT_FACE_FLAG_TRICKY                                                */
   /*                                                                       */
   /*    FT_HAS_HORIZONTAL                                                  */
   /*    FT_HAS_VERTICAL                                                    */
@@ -266,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.                               */
   /*                                                                       */
@@ -350,10 +349,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    */
@@ -422,9 +421,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;
 
@@ -435,8 +434,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;
 
@@ -447,10 +446,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;
 
@@ -468,15 +467,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).   */
   /*                                                                       */
@@ -501,11 +500,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.                                                           */
@@ -532,9 +531,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, */
@@ -553,13 +551,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.   */
@@ -616,8 +615,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        */
@@ -631,18 +630,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'.                   */
@@ -651,12 +649,12 @@
   /*      Area) in the range U+F020-U+F0FF.                                */
   /*                                                                       */
   /*    FT_ENCODING_SJIS ::                                                */
-  /*      Corresponds to Japanese SJIS encoding.  More info at             */
-  /*      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 */
+  /*      Corresponds to an encoding system for Simplified Chinese as      */
   /*      used in mainland China.                                          */
   /*                                                                       */
   /*    FT_ENCODING_BIG5 ::                                                */
@@ -664,9 +662,10 @@
   /*      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        */
@@ -678,26 +677,24 @@
   /*      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 ::                                             */
@@ -717,7 +714,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.                                                    */
@@ -821,11 +818,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_
@@ -853,8 +850,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.                    */
@@ -874,7 +871,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  */
@@ -882,14 +879,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).   */
@@ -903,17 +901,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  */
@@ -952,6 +951,10 @@
   /*                           strikes in the face.  It is set to NULL if  */
   /*                           there is no bitmap strike.                  */
   /*                                                                       */
+  /*                           Note that FreeType tries to sanitize the    */
+  /*                           strike data since they are sometimes sloppy */
+  /*                           or incorrect, but this can easily fail.     */
+  /*                                                                       */
   /*    num_charmaps        :: The number of charmaps in the face.         */
   /*                                                                       */
   /*    charmaps            :: An array of the charmaps of the face.       */
@@ -987,8 +990,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,          */
@@ -1031,6 +1034,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;
@@ -1102,49 +1111,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      */
-  /*      and @FT_FACE_FLAG_FIXED_SIZES set.                               */
+  /*      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, Lucido,  */
+  /*      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 ::                                    */
@@ -1153,31 +1164,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                     */
@@ -1189,8 +1200,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 )
@@ -1223,7 +1234,7 @@
    *
    */
 #define FT_HAS_HORIZONTAL( face ) \
-          ( face->face_flags & FT_FACE_FLAG_HORIZONTAL )
+          ( (face)->face_flags & FT_FACE_FLAG_HORIZONTAL )
 
 
   /*************************************************************************
@@ -1237,7 +1248,7 @@
    *
    */
 #define FT_HAS_VERTICAL( face ) \
-          ( face->face_flags & FT_FACE_FLAG_VERTICAL )
+          ( (face)->face_flags & FT_FACE_FLAG_VERTICAL )
 
 
   /*************************************************************************
@@ -1251,7 +1262,7 @@
    *
    */
 #define FT_HAS_KERNING( face ) \
-          ( face->face_flags & FT_FACE_FLAG_KERNING )
+          ( (face)->face_flags & FT_FACE_FLAG_KERNING )
 
 
   /*************************************************************************
@@ -1262,11 +1273,11 @@
    * @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 ) \
-          ( face->face_flags & FT_FACE_FLAG_SCALABLE )
+          ( (face)->face_flags & FT_FACE_FLAG_SCALABLE )
 
 
   /*************************************************************************
@@ -1285,7 +1296,7 @@
    *
    */
 #define FT_IS_SFNT( face ) \
-          ( face->face_flags & FT_FACE_FLAG_SFNT )
+          ( (face)->face_flags & FT_FACE_FLAG_SFNT )
 
 
   /*************************************************************************
@@ -1300,7 +1311,7 @@
    *
    */
 #define FT_IS_FIXED_WIDTH( face ) \
-          ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH )
+          ( (face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH )
 
 
   /*************************************************************************
@@ -1315,7 +1326,7 @@
    *
    */
 #define FT_HAS_FIXED_SIZES( face ) \
-          ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES )
+          ( (face)->face_flags & FT_FACE_FLAG_FIXED_SIZES )
 
 
   /*************************************************************************
@@ -1341,7 +1352,7 @@
    *
    */
 #define FT_HAS_GLYPH_NAMES( face ) \
-          ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES )
+          ( (face)->face_flags & FT_FACE_FLAG_GLYPH_NAMES )
 
 
   /*************************************************************************
@@ -1356,7 +1367,21 @@
    *
    */
 #define FT_HAS_MULTIPLE_MASTERS( face ) \
-          ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS )
+          ( (face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS )
+
+
+  /*************************************************************************
+   *
+   * @macro:
+   *   FT_IS_NAMED_INSTANCE( face )
+   *
+   * @description:
+   *   A macro that returns true whenever a face object is a named instance
+   *   of a GX or OpenType variation font.
+   *
+   */
+#define FT_IS_NAMED_INSTANCE( face ) \
+          ( (face)->face_index & 0x7FFF0000L )
 
 
   /*************************************************************************
@@ -1374,7 +1399,7 @@
    *
    */
 #define FT_IS_CID_KEYED( face ) \
-          ( face->face_flags & FT_FACE_FLAG_CID_KEYED )
+          ( (face)->face_flags & FT_FACE_FLAG_CID_KEYED )
 
 
   /*************************************************************************
@@ -1388,7 +1413,7 @@
    *
    */
 #define FT_IS_TRICKY( face ) \
-          ( face->face_flags & FT_FACE_FLAG_TRICKY )
+          ( (face)->face_flags & FT_FACE_FLAG_TRICKY )
 
 
   /*************************************************************************
@@ -1402,7 +1427,7 @@
    *
    */
 #define FT_HAS_COLOR( face ) \
-          ( face->face_flags & FT_FACE_FLAG_COLOR )
+          ( (face)->face_flags & FT_FACE_FLAG_COLOR )
 
 
   /*************************************************************************/
@@ -1411,15 +1436,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 */
@@ -1460,12 +1485,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.                                      */
@@ -1496,7 +1521,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_
   {
@@ -1636,8 +1661,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                       */
@@ -1652,10 +1677,9 @@
   /*                         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                        */
@@ -1677,15 +1701,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       */
@@ -1702,7 +1724,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 */
@@ -1714,7 +1736,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':                                       */
   /*                                                                       */
@@ -1724,8 +1745,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'>                              */
   /*                                                                       */
@@ -1742,6 +1763,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;
@@ -1884,7 +1911,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>                                                              */
@@ -1910,9 +1937,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        */
@@ -1927,9 +1954,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.                     */
   /*                                                                       */
@@ -1942,7 +1970,7 @@
   /*                                                                       */
   /*    If the @FT_OPEN_MEMORY bit is set, assume that this is a           */
   /*    memory file of `memory_size' bytes, located at `memory_address'.   */
-  /*    The data are are not copied, and the client is responsible for     */
+  /*    The data are not copied, and the client is responsible for         */
   /*    releasing and destroying them _after_ the corresponding call to    */
   /*    @FT_Done_Face.                                                     */
   /*                                                                       */
@@ -1982,7 +2010,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.                    */
@@ -2017,8 +2045,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.                    */
@@ -2070,20 +2098,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        */
@@ -2092,10 +2121,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.         */
   /*                                                                       */
@@ -2202,7 +2231,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.                            */
@@ -2246,7 +2275,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,
@@ -2309,7 +2338,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.                  */
@@ -2321,6 +2353,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 );
@@ -2332,17 +2378,26 @@
   /*    FT_Size_Request_Type                                               */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    An enumeration type that lists the supported size request types.   */
+  /*    An enumeration type that lists the supported size request types,   */
+  /*    i.e., what input size (in font units) maps to the requested output */
+  /*    size (in pixels, as computed from the arguments of                 */
+  /*    @FT_Size_Request).                                                 */
   /*                                                                       */
   /* <Values>                                                              */
   /*    FT_SIZE_REQUEST_TYPE_NOMINAL ::                                    */
   /*      The nominal size.  The `units_per_EM' field of @FT_FaceRec is    */
   /*      used to determine both scaling values.                           */
   /*                                                                       */
+  /*      This is the standard scaling found in most applications.  In     */
+  /*      particular, use this size request type for TrueType fonts if     */
+  /*      they provide optical scaling or something similar.  Note,        */
+  /*      however, that `units_per_EM' is a rather abstract value which    */
+  /*      bears no relation to the actual size of the glyphs in a font.    */
+  /*                                                                       */
   /*    FT_SIZE_REQUEST_TYPE_REAL_DIM ::                                   */
-  /*      The real dimension.  The sum of the the `ascender' and (minus    */
-  /*      of) the `descender' fields of @FT_FaceRec are used to determine  */
-  /*      both scaling values.                                             */
+  /*      The real dimension.  The sum of the `ascender' and (minus of)    */
+  /*      the `descender' fields of @FT_FaceRec is used to determine both  */
+  /*      scaling values.                                                  */
   /*                                                                       */
   /*    FT_SIZE_REQUEST_TYPE_BBOX ::                                       */
   /*      The font bounding box.  The width and height of the `bbox' field */
@@ -2387,27 +2442,36 @@
   /*    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.                       */
   /*                                                                       */
-  /*    width          :: The desired width.                               */
+  /*    width          :: The desired width, given as a 26.6 fractional    */
+  /*                      point value (with 72pt = 1in).                   */
   /*                                                                       */
-  /*    height         :: The desired height.                              */
+  /*    height         :: The desired height, given as a 26.6 fractional   */
+  /*                      point value (with 72pt = 1in).                   */
   /*                                                                       */
-  /*    horiResolution :: The horizontal resolution.  If set to zero,      */
-  /*                      `width' is treated as a 26.6 fractional pixel    */
-  /*                      value.                                           */
+  /*    horiResolution :: The horizontal resolution (dpi, i.e., pixels per */
+  /*                      inch).  If set to zero, `width' is treated as a  */
+  /*                      26.6 fractional *pixel* value, which gets        */
+  /*                      internally rounded to an integer.                */
   /*                                                                       */
-  /*    vertResolution :: The vertical resolution.  If set to zero,        */
-  /*                      `height' is treated as a 26.6 fractional pixel   */
-  /*                      value.                                           */
+  /*    vertResolution :: The vertical resolution (dpi, i.e., pixels per   */
+  /*                      inch).  If set to zero, `height' is treated as a */
+  /*                      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 */
+  /*    interpreted directly as 16.16 fractional scaling values, without   */
+  /*    any further modification, and both `horiResolution' and            */
+  /*    `vertResolution' are ignored.                                      */
+  /*                                                                       */
   typedef struct  FT_Size_RequestRec_
   {
     FT_Size_Request_Type  type;
@@ -2457,7 +2521,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.   */
   /*                                                                       */
@@ -2472,8 +2536,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.               */
@@ -2491,6 +2554,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.                                                */
   /*                                                                       */
@@ -2516,8 +2583,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.                */
@@ -2531,8 +2597,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.   */
@@ -2549,8 +2615,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  */
@@ -2579,6 +2644,10 @@
   /*    don't have a corresponding glyph in the font).  See the discussion */
   /*    of the @FT_FACE_FLAG_CID_KEYED flag for more details.              */
   /*                                                                       */
+  /*    If you receive `FT_Err_Glyph_Too_Big', try getting the glyph       */
+  /*    outline at EM size, then scale it manually and fill it as a        */
+  /*    graphics operation.                                                */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Load_Glyph( FT_Face   face,
                  FT_UInt   glyph_index,
@@ -2591,8 +2660,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    */
@@ -2614,6 +2683,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,
@@ -2626,8 +2699,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 ::
@@ -2639,13 +2712,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.
    *
@@ -2692,13 +2765,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
@@ -2706,17 +2779,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
@@ -2728,31 +2800,37 @@
    *     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 ::
+   *     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.
+   *
    *   FT_LOAD_CROP_BITMAP ::
    *     Ignored.  Deprecated.
    *
@@ -2796,13 +2874,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 )
 
@@ -2813,29 +2892,30 @@
    *   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.
-   *
-   *   Also note that @FT_LOAD_TARGET_LIGHT is an exception, in that it
-   *   always implies @FT_LOAD_FORCE_AUTOHINT.
+   *   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 non-monochrome modes.  Many
-   *     generated glyphs are more fuzzy but better resemble its original
-   *     shape.  A bit like rendering on Mac OS~X.
-   *
-   *     As a special exception, this target implies @FT_LOAD_FORCE_AUTOHINT.
+   *     A lighter hinting algorithm for gray-level modes.  Many generated
+   *     glyphs are fuzzier but better resemble their original shape.  This
+   *     is achieved by snapping glyphs to the pixel grid only vertically
+   *     (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
+   *     auto-hinter.
    *
    *   FT_LOAD_TARGET_MONO ::
    *     Strong hinting algorithm that should only be used for monochrome
@@ -2856,7 +2936,7 @@
    *
    *   If @FT_LOAD_RENDER is also set, the glyph is rendered in the
    *   corresponding mode (i.e., the mode that matches the used algorithm
-   *   best).  An exeption is FT_LOAD_TARGET_MONO since it implies
+   *   best).  An exception is FT_LOAD_TARGET_MONO since it implies
    *   @FT_LOAD_MONOCHROME.
    *
    *   You can use a hinting algorithm that doesn't correspond to the same
@@ -2900,18 +2980,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 */
@@ -2934,20 +3013,22 @@
   /*    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    */
   /*    returned bitmap.                                                   */
   /*                                                                       */
-  /*    All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity.   */
+  /*    All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity,   */
+  /*    indicating pixel coverage.  Use linear alpha blending and gamma    */
+  /*    correction to correctly render non-monochrome glyph bitmaps onto a */
+  /*    surface; see @FT_Render_Glyph.                                     */
   /*                                                                       */
   /* <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        */
@@ -2972,11 +3053,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            */
@@ -3017,16 +3098,93 @@
   /*                   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         */
+  /*    filled-in outline, the bitmap contains 0xFF at that pixel, meaning */
+  /*    that 0xFF/0xFF fraction of that pixel is covered, meaning the      */
+  /*    pixel is 100% black (or 0% bright).  If a pixel is only 50%        */
+  /*    covered (value 0x80), the pixel is made 50% black (50% bright or a */
+  /*    middle shade of grey).  0% covered means 0% black (100% bright or  */
+  /*    white).                                                            */
+  /*                                                                       */
+  /*    On high-DPI screens like on smartphones and tablets, the pixels    */
+  /*    are so small that their chance of being completely covered and     */
+  /*    therefore completely black are fairly good.  On the low-DPI        */
+  /*    screens, however, the situation is different.  The pixels are too  */
+  /*    large for most of the details of a glyph and shades of gray are    */
+  /*    the norm rather than the exception.                                */
+  /*                                                                       */
+  /*    This is relevant because all our screens have a second problem:    */
+  /*    they are not linear.  1~+~1 is not~2.  Twice the value does not    */
+  /*    result in twice the brightness.  When a pixel is only 50% covered, */
+  /*    the coverage map says 50% black, and this translates to a pixel    */
+  /*    value of 128 when you use 8~bits per channel (0-255).  However,    */
+  /*    this does not translate to 50% brightness for that pixel on our    */
+  /*    sRGB and gamma~2.2 screens.  Due to their non-linearity, they      */
+  /*    dwell longer in the darks and only a pixel value of about 186      */
+  /*    results in 50% brightness – 128 ends up too dark on both bright    */
+  /*    and dark backgrounds.  The net result is that dark text looks      */
+  /*    burnt-out, pixely and blotchy on bright background, bright text    */
+  /*    too frail on dark backgrounds, and colored text on colored         */
+  /*    background (for example, red on green) seems to have dark halos or */
+  /*    `dirt' around it.  The situation is especially ugly for diagonal   */
+  /*    stems like in `w' glyph shapes where the quality of FreeType's     */
+  /*    anti-aliasing depends on the correct display of grays.  On         */
+  /*    high-DPI screens where smaller, fully black pixels reign supreme,  */
+  /*    this doesn't matter, but on our low-DPI screens with all the gray  */
+  /*    shades, it does.  0% and 100% brightness are the same things in    */
+  /*    linear and non-linear space, just all the shades in-between        */
+  /*    aren't.                                                            */
+  /*                                                                       */
+  /*    The blending function for placing text over a background is        */
+  /*                                                                       */
+  /*    {                                                                  */
+  /*      dst = alpha * src + (1 - alpha) * dst    ,                       */
+  /*    }                                                                  */
+  /*                                                                       */
+  /*    which is known as the OVER operator.                               */
+  /*                                                                       */
+  /*    To correctly composite an antialiased pixel of a glyph onto a      */
+  /*    surface,                                                           */
+  /*                                                                       */
+  /*    1. take the foreground and background colors (e.g., in sRGB space) */
+  /*       and apply gamma to get them in a linear space,                  */
+  /*                                                                       */
+  /*    2. use OVER to blend the two linear colors using the glyph pixel   */
+  /*       as the alpha value (remember, the glyph bitmap is an alpha      */
+  /*       coverage bitmap), and                                           */
+  /*                                                                       */
+  /*    3. apply inverse gamma to the blended pixel and write it back to   */
+  /*       the image.                                                      */
+  /*                                                                       */
+  /*    Internal testing at Adobe found that a target inverse gamma of~1.8 */
+  /*    for step~3 gives good results across a wide range of displays with */
+  /*    an sRGB gamma curve or a similar one.                              */
+  /*                                                                       */
+  /*    This process can cost performance.  There is an approximation that */
+  /*    does not need to know about the background color; see              */
+  /*    https://bel.fi/alankila/lcd/ and                                   */
+  /*    https://bel.fi/alankila/lcd/alpcor.html for details.               */
+  /*                                                                       */
+  /*    *ATTENTION*: Linear blending is even more important when dealing   */
+  /*    with subpixel-rendered glyphs to prevent color-fringing!  A        */
+  /*    subpixel-rendered glyph must first be filtered with a filter that  */
+  /*    gives equal weight to the three color primaries and does not       */
+  /*    exceed a sum of 0x100, see section @lcd_filtering.  Then the       */
+  /*    only difference to gray linear blending is that subpixel-rendered  */
+  /*    linear blending is done 3~times per pixel: red foreground subpixel */
+  /*    to red background subpixel and so on for green and blue.           */
   /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Render_Glyph( FT_GlyphSlot    slot,
@@ -3039,17 +3197,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.                                      */
@@ -3059,9 +3215,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
 
@@ -3081,7 +3241,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.                   */
@@ -3109,6 +3269,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,
@@ -3148,7 +3312,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,
@@ -3194,7 +3358,7 @@
   /*    `.notdef').                                                        */
   /*                                                                       */
   /*    This function always returns an error if the config macro          */
-  /*    `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoptions.h'. */
+  /*    `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoption.h'.  */
   /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Get_Glyph_Name( FT_Face     face,
@@ -3210,7 +3374,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.                        */
@@ -3281,7 +3445,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,
@@ -3316,7 +3481,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.                    */
@@ -3350,9 +3515,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.                     */
@@ -3365,7 +3529,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:                                             */
   /*                                                                       */
@@ -3405,12 +3569,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>                                                              */
@@ -3423,7 +3588,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.                                                       */
@@ -3440,8 +3605,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.                  */
@@ -3462,8 +3626,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 ::
@@ -3524,7 +3690,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 )
@@ -3564,33 +3730,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
@@ -3606,13 +3770,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 */
@@ -3652,8 +3816,9 @@
   /*    Database:                                                          */
   /*                                                                       */
   /*      http://www.unicode.org/reports/tr37/                             */
+  /*      http://www.unicode.org/ivd/                                      */
   /*                                                                       */
-  /*    To date (November 2014), the character with the most variants is   */
+  /*    To date (January 2017), the character with the most variants is    */
   /*    U+9089, having 32 such IVS.                                        */
   /*                                                                       */
   /*    Adobe and MS decided to support IVS with a new cmap subtable       */
@@ -3882,16 +4047,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>                                                              */
@@ -3911,12 +4077,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).                                    */
   /*                                                                       */
@@ -3945,12 +4111,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>                                                              */
@@ -3967,13 +4133,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 )
@@ -3986,8 +4152,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.  */
@@ -4005,8 +4170,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.    */
@@ -4092,7 +4256,7 @@
    *
    */
 #define FREETYPE_MAJOR  2
-#define FREETYPE_MINOR  6
+#define FREETYPE_MINOR  7
 #define FREETYPE_PATCH  1
 
 
@@ -4138,20 +4302,13 @@
   /*    FT_Face_CheckTrueTypePatents                                       */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Parse all bytecode instructions of a TrueType font file to check   */
-  /*    whether any of the patented opcodes are used.  This is only useful */
-  /*    if you want to be able to use the unpatented hinter with           */
-  /*    fonts that do *not* use these opcodes.                             */
-  /*                                                                       */
-  /*    Note that this function parses *all* glyph instructions in the     */
-  /*    font file, which may be slow.                                      */
+  /*    Deprecated, does nothing.                                          */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face :: A face handle.                                             */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    1~if this is a TrueType font that uses one of the patented         */
-  /*    opcodes, 0~otherwise.                                              */
+  /*    Always returns false.                                              */
   /*                                                                       */
   /* <Note>                                                                */
   /*    Since May 2010, TrueType hinting is no longer patented.            */
@@ -4169,9 +4326,7 @@
   /*    FT_Face_SetUnpatentedHinting                                       */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Enable or disable the unpatented hinter for a given face.          */
-  /*    Only enable it if you have determined that the face doesn't        */
-  /*    use any patented opcodes (see @FT_Face_CheckTrueTypePatents).      */
+  /*    Deprecated, does nothing.                                          */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face  :: A face handle.                                            */
@@ -4179,9 +4334,7 @@
   /*    value :: New boolean setting.                                      */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    The old setting value.  This will always be false if this is not   */
-  /*    an SFNT font, or if the unpatented hinter is not compiled in this  */
-  /*    instance of the library.                                           */
+  /*    Always returns false.                                              */
   /*                                                                       */
   /* <Note>                                                                */
   /*    Since May 2010, TrueType hinting is no longer patented.            */
@@ -4198,7 +4351,7 @@
 
 FT_END_HEADER
 
-#endif /* __FREETYPE_H__ */
+#endif /* FREETYPE_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftadvanc.h b/third_party/freetype/include/freetype/ftadvanc.h
index b4d2aed..dea96e0 100644
--- a/third_party/freetype/include/freetype/ftadvanc.h
+++ b/third_party/freetype/include/freetype/ftadvanc.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Quick computation of advance widths (specification only).            */
 /*                                                                         */
-/*  Copyright 2008-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTADVANC_H__
-#define __FTADVANC_H__
+#ifndef FTADVANC_H_
+#define FTADVANC_H_
 
 
 #include <ft2build.h>
@@ -181,7 +181,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTADVANC_H__ */
+#endif /* FTADVANC_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftbitmap.h b/third_party/freetype/include/freetype/ftbitmap.h
index 46cc47b..04b2402 100644
--- a/third_party/freetype/include/freetype/ftbitmap.h
+++ b/third_party/freetype/include/freetype/ftbitmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility functions for bitmaps (specification).              */
 /*                                                                         */
-/*  Copyright 2004-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTBITMAP_H__
-#define __FTBITMAP_H__
+#ifndef FTBITMAP_H_
+#define FTBITMAP_H_
 
 
 #include <ft2build.h>
@@ -234,7 +234,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTBITMAP_H__ */
+#endif /* FTBITMAP_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftcffdrv.h b/third_party/freetype/include/freetype/ftcffdrv.h
index 6c8e416..35758f8 100644
--- a/third_party/freetype/include/freetype/ftcffdrv.h
+++ b/third_party/freetype/include/freetype/ftcffdrv.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for controlling the CFF driver (specification only).    */
 /*                                                                         */
-/*  Copyright 2013-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTCFFDRV_H__
-#define __FTCFFDRV_H__
+#ifndef FTCFFDRV_H_
+#define FTCFFDRV_H_
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
@@ -89,7 +89,7 @@
    *   features preserve the design's weight and spacing much better than
    *   aliased type would.
    *
-   *   2) Aligment in the vertical direction: Weights and spacing along the
+   *   2) Alignment in the vertical direction: Weights and spacing along the
    *   y~axis are less critical; what is much more important is the visual
    *   alignment of related features (like cap-height and x-height).  The
    *   sense of alignment for these is enhanced by the sharpness of grid-fit
@@ -110,9 +110,9 @@
    *   to minimize distortion.
    *
    * @order:
-   *   hinting-engine
-   *   no-stem-darkening
-   *   darkening-parameters
+   *   hinting-engine[cff]
+   *   no-stem-darkening[cff]
+   *   darkening-parameters[cff]
    *
    */
 
@@ -120,7 +120,7 @@
   /**************************************************************************
    *
    * @property:
-   *   hinting-engine
+   *   hinting-engine[cff]
    *
    * @description:
    *   Thanks to Adobe, which contributed a new hinting (and parsing)
@@ -148,6 +148,8 @@
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
+   *   This property can be set via the `FREETYPE_PROPERTIES' environment
+   *   variable (using values `adobe' or `freetype').
    */
 
 
@@ -157,8 +159,8 @@
    *   FT_CFF_HINTING_XXX
    *
    * @description:
-   *   A list of constants used for the @hinting-engine property to select
-   *   the hinting engine for CFF fonts.
+   *   A list of constants used for the @hinting-engine[cff] property to
+   *   select the hinting engine for CFF fonts.
    *
    * @values:
    *   FT_CFF_HINTING_FREETYPE ::
@@ -175,7 +177,7 @@
   /**************************************************************************
    *
    * @property:
-   *   no-stem-darkening
+   *   no-stem-darkening[cff]
    *
    * @description:
    *   By default, the Adobe CFF engine darkens stems at smaller sizes,
@@ -199,13 +201,16 @@
    * @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).
+   *
    */
 
 
   /**************************************************************************
    *
    * @property:
-   *   darkening-parameters
+   *   darkening-parameters[cff]
    *
    * @description:
    *   By default, the Adobe CFF engine darkens stems as follows (if the
@@ -248,6 +253,14 @@
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
+   *   This property can be set via the `FREETYPE_PROPERTIES' environment
+   *   variable, using eight comma-separated integers without spaces.  Here
+   *   the above example, using `\' to break the line for readability.
+   *
+   *   {
+   *     FREETYPE_PROPERTIES=\
+   *     cff:darkening-parameters=500,300,1000,200,1500,100,2000,0
+   *   }
    */
 
   /* */
@@ -256,7 +269,7 @@
 FT_END_HEADER
 
 
-#endif /* __FTCFFDRV_H__ */
+#endif /* FTCFFDRV_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/fterrdef.h b/third_party/freetype/include/freetype/fterrdef.h
index d865da7..232dccd 100644
--- a/third_party/freetype/include/freetype/fterrdef.h
+++ b/third_party/freetype/include/freetype/fterrdef.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType error codes (specification).                                */
 /*                                                                         */
-/*  Copyright 2002-2015 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,       */
@@ -243,7 +243,7 @@
   FT_ERRORDEF_( No_Unicode_Glyph_Name,                       0xA3,
                 "no Unicode glyph name found" )
   FT_ERRORDEF_( Glyph_Too_Big,                               0xA4,
-                "glyph to big for hinting" )
+                "glyph too big for hinting" )
 
   /* BDF errors */
 
diff --git a/third_party/freetype/include/freetype/fterrors.h b/third_party/freetype/include/freetype/fterrors.h
index 0507b9a..021989d 100644
--- a/third_party/freetype/include/freetype/fterrors.h
+++ b/third_party/freetype/include/freetype/fterrors.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType error code handling (specification).                        */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -72,13 +72,13 @@
   /*                                                                       */
   /*   This macro ends the list.                                           */
   /*                                                                       */
-  /*   Additionally, you have to undefine `__FTERRORS_H__' before          */
-  /*   #including this file.                                               */
+  /*   Additionally, you have to undefine `FTERRORS_H_' before #including  */
+  /*   this file.                                                          */
   /*                                                                       */
   /*   Here is a simple example.                                           */
   /*                                                                       */
   /*   {                                                                   */
-  /*     #undef __FTERRORS_H__                                             */
+  /*     #undef FTERRORS_H_                                                */
   /*     #define FT_ERRORDEF( e, v, s )  { e, s },                         */
   /*     #define FT_ERROR_START_LIST     {                                 */
   /*     #define FT_ERROR_END_LIST       { 0, NULL } };                    */
@@ -99,7 +99,17 @@
 
   /* */
 
-#ifndef __FTERRORS_H__
+  /* In previous FreeType versions we used `__FTERRORS_H__'.  However, */
+  /* using two successive underscores in a non-system symbol name      */
+  /* violates the C (and C++) standard, so it was changed to the       */
+  /* current form.  In spite of this, we have to make                  */
+  /*                                                                   */
+  /*   #undefine __FTERRORS_H__                                        */
+  /*                                                                   */
+  /* work for backwards compatibility.                                 */
+  /*                                                                   */
+#if !( defined( FTERRORS_H_ ) && defined ( __FTERRORS_H__ ) )
+#define FTERRORS_H_
 #define __FTERRORS_H__
 
 
@@ -210,7 +220,7 @@
 #undef FT_ERR_PREFIX
 #endif
 
-#endif /* __FTERRORS_H__ */
+#endif /* !(FTERRORS_H_ && __FTERRORS_H__) */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftfntfmt.h b/third_party/freetype/include/freetype/ftfntfmt.h
index 1f8ff28..3377583 100644
--- a/third_party/freetype/include/freetype/ftfntfmt.h
+++ b/third_party/freetype/include/freetype/ftfntfmt.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Support functions for font formats.                                  */
 /*                                                                         */
-/*  Copyright 2002-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTFNTFMT_H__
-#define __FTFNTFMT_H__
+#ifndef FTFNTFMT_H_
+#define FTFNTFMT_H_
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
@@ -89,4 +89,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTFNTFMT_H__ */
+#endif /* FTFNTFMT_H_ */
+
+
+/* END */
diff --git a/third_party/freetype/include/freetype/ftglyph.h b/third_party/freetype/include/freetype/ftglyph.h
index 803ad39..6b51792 100644
--- a/third_party/freetype/include/freetype/ftglyph.h
+++ b/third_party/freetype/include/freetype/ftglyph.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType convenience functions to handle glyphs (specification).     */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -29,8 +29,8 @@
   /*************************************************************************/
 
 
-#ifndef __FTGLYPH_H__
-#define __FTGLYPH_H__
+#ifndef FTGLYPH_H_
+#define FTGLYPH_H_
 
 
 #include <ft2build.h>
@@ -594,7 +594,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTGLYPH_H__ */
+#endif /* FTGLYPH_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftgzip.h b/third_party/freetype/include/freetype/ftgzip.h
index b3a532d..bd5ceaa 100644
--- a/third_party/freetype/include/freetype/ftgzip.h
+++ b/third_party/freetype/include/freetype/ftgzip.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Gzip-compressed stream support.                                      */
 /*                                                                         */
-/*  Copyright 2002-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTGZIP_H__
-#define __FTGZIP_H__
+#ifndef FTGZIP_H_
+#define FTGZIP_H_
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
@@ -117,11 +117,11 @@
   *
   * @inout:
   *   output_len ::
-  *     Before calling the function, this is the the total size of the
-  *     output buffer, which must be large enough to hold the entire
-  *     uncompressed data (so the size of the uncompressed data must be
-  *     known in advance).  After calling the function, `output_len' is the
-  *     size of the used data in `output'.
+  *     Before calling the function, this is the total size of the output
+  *     buffer, which must be large enough to hold the entire uncompressed
+  *     data (so the size of the uncompressed data must be known in
+  *     advance).  After calling the function, `output_len' is the size of
+  *     the used data in `output'.
   *
   * @return:
   *   FreeType error code.  0~means success.
@@ -142,7 +142,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTGZIP_H__ */
+#endif /* FTGZIP_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftimage.h b/third_party/freetype/include/freetype/ftimage.h
index 82f284c..e21a220 100644
--- a/third_party/freetype/include/freetype/ftimage.h
+++ b/third_party/freetype/include/freetype/ftimage.h
@@ -5,7 +5,7 @@
 /*    FreeType glyph image formats and default raster interface            */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 1996-2015 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,12 +24,12 @@
   /*************************************************************************/
 
 
-#ifndef __FTIMAGE_H__
-#define __FTIMAGE_H__
+#ifndef FTIMAGE_H_
+#define FTIMAGE_H_
 
 
-  /* _STANDALONE_ is from ftgrays.c */
-#ifndef _STANDALONE_
+  /* STANDALONE_ is from ftgrays.c */
+#ifndef STANDALONE_
 #include <ft2build.h>
 #endif
 
@@ -747,7 +747,7 @@
   /*************************************************************************/
   /*                                                                       */
   /* A raster is a scan converter, in charge of rendering an outline into  */
-  /* a a bitmap.  This section contains the public API for rasters.        */
+  /* a bitmap.  This section contains the public API for rasters.          */
   /*                                                                       */
   /* Note that in FreeType 2, all rasters are now encapsulated within      */
   /* specific modules called `renderers'.  See `ftrender.h' for more       */
@@ -860,16 +860,6 @@
   /*    This can be used to write anti-aliased outlines directly to a      */
   /*    given background bitmap, and even perform translucency.            */
   /*                                                                       */
-  /*    Note that the `count' field cannot be greater than a fixed value   */
-  /*    defined by the `FT_MAX_GRAY_SPANS' configuration macro in          */
-  /*    `ftoption.h'.  By default, this value is set to~32, which means    */
-  /*    that if there are more than 32~spans on a given scanline, the      */
-  /*    callback is called several times with the same `y' parameter in    */
-  /*    order to draw all callbacks.                                       */
-  /*                                                                       */
-  /*    Otherwise, the callback is only called once per scan-line, and     */
-  /*    only for those scanlines that do have `gray' pixels on them.       */
-  /*                                                                       */
   typedef void
   (*FT_SpanFunc)( int             y,
                   int             count,
@@ -1190,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;
@@ -1203,7 +1194,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTIMAGE_H__ */
+#endif /* FTIMAGE_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftincrem.h b/third_party/freetype/include/freetype/ftincrem.h
index 840af25..f6ae2ba 100644
--- a/third_party/freetype/include/freetype/ftincrem.h
+++ b/third_party/freetype/include/freetype/ftincrem.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType incremental loading (specification).                        */
 /*                                                                         */
-/*  Copyright 2002-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTINCREM_H__
-#define __FTINCREM_H__
+#ifndef FTINCREM_H_
+#define FTINCREM_H_
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
@@ -348,7 +348,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTINCREM_H__ */
+#endif /* FTINCREM_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftlcdfil.h b/third_party/freetype/include/freetype/ftlcdfil.h
index 4cd999a..928bb0f 100644
--- a/third_party/freetype/include/freetype/ftlcdfil.h
+++ b/third_party/freetype/include/freetype/ftlcdfil.h
@@ -5,7 +5,7 @@
 /*    FreeType API for color filtering of subpixel bitmap glyphs           */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2006-2015 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,       */
@@ -17,8 +17,8 @@
 /***************************************************************************/
 
 
-#ifndef __FT_LCD_FILTER_H__
-#define __FT_LCD_FILTER_H__
+#ifndef FTLCDFIL_H_
+#define FTLCDFIL_H_
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
@@ -41,56 +41,91 @@
    *   LCD Filtering
    *
    * @abstract:
-   *   Reduce color fringes of LCD-optimized bitmaps.
+   *   Reduce color fringes of subpixel-rendered bitmaps.
    *
    * @description:
-   *   The @FT_Library_SetLcdFilter API can be used to specify a low-pass
-   *   filter, which is then applied to LCD-optimized bitmaps generated
-   *   through @FT_Render_Glyph.  This is useful to reduce color fringes
-   *   that would occur with unfiltered rendering.
+   *   Subpixel rendering exploits the color-striped structure of LCD
+   *   pixels, increasing the available resolution in the direction of the
+   *   stripe (usually horizontal RGB) by a factor of~3.  Since these
+   *   subpixels are color pixels, using them unfiltered creates severe
+   *   color fringes.  Use the @FT_Library_SetLcdFilter API to specify a
+   *   low-pass filter, which is then applied to subpixel-rendered bitmaps
+   *   generated through @FT_Render_Glyph.  The filter sacrifices some of
+   *   the higher resolution to reduce color fringes, making the glyph image
+   *   slightly blurrier.  Positional improvements will remain.
    *
    *   Note that no filter is active by default, and that this function is
    *   *not* implemented in default builds of the library.  You need to
    *   #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file
-   *   in order to activate it.
+   *   in order to activate it and explicitly call @FT_Library_SetLcdFilter
+   *   to enable it.
    *
-   *   FreeType generates alpha coverage maps, which are linear by nature.
-   *   For instance, the value 0x80 in bitmap representation means that
-   *   (within numerical precision) 0x80/0xFF fraction of that pixel is
-   *   covered by the glyph's outline.  The blending function for placing
-   *   text over a background is
+   *   A filter should have two properties:
    *
-   *   {
-   *     dst = alpha * src + (1 - alpha) * dst    ,
-   *   }
+   *   1) It should be normalized, meaning the sum of the 5~components
+   *      should be 256 (0x100).  It is possible to go above or under this
+   *      target sum, however: going under means tossing out contrast, going
+   *      over means invoking clamping and thereby non-linearities that
+   *      increase contrast somewhat at the expense of greater distortion
+   *      and color-fringing.  Contrast is better enhanced through stem
+   *      darkening.
    *
-   *   which is known as OVER.  However, when calculating the output of the
-   *   OVER operator, the source colors should first be transformed to a
-   *   linear color space, then alpha blended in that space, and transformed
-   *   back to the output color space.
+   *   2) It should be color-balanced, meaning a filter `{~a, b, c, b, a~}'
+   *      where a~+ b~=~c.  It distributes the computed coverage for one
+   *      subpixel to all subpixels equally, sacrificing some won resolution
+   *      but drastically reducing color-fringing.  Positioning improvements
+   *      remain!  Note that color-fringing can only really be minimized
+   *      when using a color-balanced filter and alpha-blending the glyph
+   *      onto a surface in linear space; see @FT_Render_Glyph.
    *
-   *   When linear light blending is used, the default FIR5 filtering
-   *   weights (as given by FT_LCD_FILTER_DEFAULT) are no longer optimal, as
-   *   they have been designed for black on white rendering while lacking
-   *   gamma correction.  To preserve color neutrality, weights for a FIR5
-   *   filter should be chosen according to two free parameters `a' and `c',
-   *   and the FIR weights should be
+   *   Regarding the form, a filter can be a `boxy' filter or a `beveled'
+   *   filter.  Boxy filters are sharper but are less forgiving of non-ideal
+   *   gamma curves of a screen (viewing angles!), beveled filters are
+   *   fuzzier but more tolerant.
    *
-   *   {
-   *     [a - c, a + c, 2 * a, a + c, a - c]    .
-   *   }
+   *   Examples:
    *
-   *   This formula generates equal weights for all the color primaries
-   *   across the filter kernel, which makes it colorless.  One suggested
-   *   set of weights is
+   *   - [0x10 0x40 0x70 0x40 0x10] is beveled and neither balanced nor
+   *     normalized.
    *
-   *   {
-   *     [0x10, 0x50, 0x60, 0x50, 0x10]    ,
-   *   }
+   *   - [0x1A 0x33 0x4D 0x33 0x1A] is beveled and balanced but not
+   *     normalized.
    *
-   *   where `a' has value 0x30 and `b' value 0x20.  The weights in filter
-   *   may have a sum larger than 0x100, which increases coloration slightly
-   *   but also improves contrast.
+   *   - [0x19 0x33 0x66 0x4c 0x19] is beveled and normalized but not
+   *     balanced.
+   *
+   *   - [0x00 0x4c 0x66 0x4c 0x00] is boxily beveled and normalized but not
+   *     balanced.
+   *
+   *   - [0x00 0x55 0x56 0x55 0x00] is boxy, normalized, and almost
+   *     balanced.
+   *
+   *   - [0x08 0x4D 0x56 0x4D 0x08] is beveled, normalized and, almost
+   *     balanced.
+   *
+   *   The filter affects glyph bitmaps rendered through @FT_Render_Glyph,
+   *   @FT_Load_Glyph, and @FT_Load_Char.  It does _not_ affect the output
+   *   of @FT_Outline_Render and @FT_Outline_Get_Bitmap.
+   *
+   *   If this feature is activated, the dimensions of LCD glyph bitmaps are
+   *   either wider or taller than the dimensions of the corresponding
+   *   outline with regard to the pixel grid.  For example, for
+   *   @FT_RENDER_MODE_LCD, the filter adds 3~subpixels to the left, and
+   *   3~subpixels to the right.  The bitmap offset values are adjusted
+   *   accordingly, so clients shouldn't need to modify their layout and
+   *   glyph positioning code when enabling the filter.
+   *
+   *   It is important to understand that linear alpha blending and gamma
+   *   correction is critical for correctly rendering glyphs onto surfaces
+   *   without artifacts and even more critical when subpixel rendering is
+   *   involved.
+   *
+   *   Each of the 3~alpha values (subpixels) is independently used to blend
+   *   one color channel.  That is, red alpha blends the red channel of the
+   *   text color with the red channel of the background pixel.  The
+   *   distribution of density values by the color-balanced filter assumes
+   *   alpha blending is done in linear space; only then color artifacts
+   *   cancel out.
    */
 
 
@@ -111,10 +146,23 @@
    *     The default filter reduces color fringes considerably, at the cost
    *     of a slight blurriness in the output.
    *
+   *     It is a beveled, normalized, and color-balanced five-tap filter
+   *     that is more forgiving to screens with non-ideal gamma curves and
+   *     viewing angles.  Note that while color-fringing is reduced, it can
+   *     only be minimized by using linear alpha blending and gamma
+   *     correction to render glyphs onto surfaces.  The default filter
+   *     weights are [0x08 0x4D 0x56 0x4D 0x08].
+   *
    *   FT_LCD_FILTER_LIGHT ::
-   *     The light filter is a variant that produces less blurriness at the
-   *     cost of slightly more color fringes than the default one.  It might
-   *     be better, depending on taste, your monitor, or your personal vision.
+   *     The light filter is a variant that is sharper at the cost of
+   *     slightly more color fringes than the default one.
+   *
+   *     It is a boxy, normalized, and color-balanced three-tap filter that
+   *     is less forgiving to screens with non-ideal gamma curves and
+   *     viewing angles.  This filter works best when the rendering system
+   *     uses linear alpha blending and gamma correction to render glyphs
+   *     onto surfaces.  The light filter weights are
+   *     [0x00 0x55 0x56 0x55 0x00].
    *
    *   FT_LCD_FILTER_LEGACY ::
    *     This filter corresponds to the original libXft color filter.  It
@@ -126,14 +174,23 @@
    *     This filter is only provided for comparison purposes, and might be
    *     disabled or stay unsupported in the future.
    *
+   *   FT_LCD_FILTER_LEGACY1 ::
+   *     For historical reasons, the FontConfig library returns a different
+   *     enumeration value for legacy LCD filtering.  To make code work that
+   *     (incorrectly) forwards FontConfig's enumeration value to
+   *     @FT_Library_SetLcdFilter without proper mapping, it is thus easiest
+   *     to have another enumeration value, which is completely equal to
+   *     `FT_LCD_FILTER_LEGACY'.
+   *
    * @since:
-   *   2.3.0
+   *   2.3.0 (`FT_LCD_FILTER_LEGACY1' since 2.6.2)
    */
   typedef enum  FT_LcdFilter_
   {
     FT_LCD_FILTER_NONE    = 0,
     FT_LCD_FILTER_DEFAULT = 1,
     FT_LCD_FILTER_LIGHT   = 2,
+    FT_LCD_FILTER_LEGACY1 = 3,
     FT_LCD_FILTER_LEGACY  = 16,
 
     FT_LCD_FILTER_MAX   /* do not remove */
@@ -176,22 +233,6 @@
    *   defined in your build of the library, which should correspond to all
    *   default builds of FreeType.
    *
-   *   The filter affects glyph bitmaps rendered through @FT_Render_Glyph,
-   *   @FT_Outline_Get_Bitmap, @FT_Load_Glyph, and @FT_Load_Char.
-   *
-   *   It does _not_ affect the output of @FT_Outline_Render and
-   *   @FT_Outline_Get_Bitmap.
-   *
-   *   If this feature is activated, the dimensions of LCD glyph bitmaps are
-   *   either larger or taller than the dimensions of the corresponding
-   *   outline with regards to the pixel grid.  For example, for
-   *   @FT_RENDER_MODE_LCD, the filter adds up to 3~pixels to the left, and
-   *   up to 3~pixels to the right.
-   *
-   *   The bitmap offset values are adjusted correctly, so clients shouldn't
-   *   need to modify their layout and glyph positioning code when enabling
-   *   the filter.
-   *
    * @since:
    *   2.3.0
    */
@@ -206,11 +247,8 @@
    *   FT_Library_SetLcdFilterWeights
    *
    * @description:
-   *   Use this function to override the filter weights selected by
-   *   @FT_Library_SetLcdFilter.  By default, FreeType uses the quintuple
-   *   (0x00, 0x55, 0x56, 0x55, 0x00) for FT_LCD_FILTER_LIGHT, and (0x10,
-   *   0x40, 0x70, 0x40, 0x10) for FT_LCD_FILTER_DEFAULT and
-   *   FT_LCD_FILTER_LEGACY.
+   *   This function can be used to enable LCD filter with custom weights,
+   *   instead of using presets in @FT_Library_SetLcdFilter.
    *
    * @input:
    *   library ::
@@ -230,9 +268,6 @@
    *   defined in your build of the library, which should correspond to all
    *   default builds of FreeType.
    *
-   *   This function must be called after @FT_Library_SetLcdFilter to have
-   *   any effect.
-   *
    * @since:
    *   2.4.0
    */
@@ -245,7 +280,7 @@
 
 FT_END_HEADER
 
-#endif /* __FT_LCD_FILTER_H__ */
+#endif /* FTLCDFIL_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftlist.h b/third_party/freetype/include/freetype/ftlist.h
index 12b48c7..5309cb1 100644
--- a/third_party/freetype/include/freetype/ftlist.h
+++ b/third_party/freetype/include/freetype/ftlist.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Generic list support for FreeType (specification).                   */
 /*                                                                         */
-/*  Copyright 1996-2015 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,8 +24,8 @@
   /*************************************************************************/
 
 
-#ifndef __FTLIST_H__
-#define __FTLIST_H__
+#ifndef FTLIST_H_
+#define FTLIST_H_
 
 
 #include <ft2build.h>
@@ -270,7 +270,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTLIST_H__ */
+#endif /* FTLIST_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftmm.h b/third_party/freetype/include/freetype/ftmm.h
index 6ef4798..96dd625 100644
--- a/third_party/freetype/include/freetype/ftmm.h
+++ b/third_party/freetype/include/freetype/ftmm.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType Multiple Master font interface (specification).             */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTMM_H__
-#define __FTMM_H__
+#ifndef FTMM_H_
+#define FTMM_H_
 
 
 #include <ft2build.h>
@@ -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,31 +195,42 @@
   /*    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).                             */
   /*                                                                       */
-  /*    num_namedstyles :: The number of named styles; only meaningful for */
-  /*                       GX that allows certain design coordinates to    */
-  /*                       have a string ID (in the `name' table)          */
-  /*                       associated with them.  The font can tell the    */
-  /*                       user that, for example, Weight=1.5 is `Bold'.   */
+  /*    num_namedstyles :: The number of named styles; a `named style' is  */
+  /*                       a tuple of design coordinates that has a string */
+  /*                       ID (in the `name' table) associated with it.    */
+  /*                       The font can tell the user that, for example,   */
+  /*                       [Weight=1.5,Width=1.1] is `Bold'.               */
+  /*                                                                       */
+  /*                       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.                        */
+  /*                       Only meaningful for TrueType GX and OpenType    */
+  /*                       variation fonts.  Memory management of this     */
+  /*                       pointer is done internally by FreeType.         */
   /*                                                                       */
   typedef struct  FT_MM_Var_
   {
@@ -224,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.                            */
@@ -248,14 +274,17 @@
   /*    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.                 */
-  /*               Allocates a data structure, which the user must free.   */
+  /*    amaster :: The variation descriptor.                               */
+  /*               Allocates a data structure, which the user must         */
+  /*               deallocate with `free' after use.                       */
   /*                                                                       */
   /* <Return>                                                              */
   /*    FreeType error code.  0~means success.                             */
@@ -271,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.                         */
@@ -302,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.                         */
@@ -328,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.                         */
@@ -344,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.                             */
@@ -358,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>                                                         */
@@ -368,12 +464,26 @@
                                 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 );
+
   /* */
 
 
 FT_END_HEADER
 
-#endif /* __FTMM_H__ */
+#endif /* FTMM_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftmodapi.h b/third_party/freetype/include/freetype/ftmodapi.h
index 544279a..d5bf376 100644
--- a/third_party/freetype/include/freetype/ftmodapi.h
+++ b/third_party/freetype/include/freetype/ftmodapi.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType modules public interface (specification).                   */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTMODAPI_H__
-#define __FTMODAPI_H__
+#ifndef FTMODAPI_H_
+#define FTMODAPI_H_
 
 
 #include <ft2build.h>
@@ -111,12 +111,14 @@
 #define FT_MODULE_HINTER              4  /* this module is a glyph hinter */
 #define FT_MODULE_STYLER              8  /* this module is a styler       */
 
-#define FT_MODULE_DRIVER_SCALABLE     0x100   /* the driver supports      */
+#define FT_MODULE_DRIVER_SCALABLE      0x100  /* the driver supports      */
                                               /* scalable fonts           */
-#define FT_MODULE_DRIVER_NO_OUTLINES  0x200   /* the driver does not      */
+#define FT_MODULE_DRIVER_NO_OUTLINES   0x200  /* the driver does not      */
                                               /* support vector outlines  */
-#define FT_MODULE_DRIVER_HAS_HINTER   0x400   /* the driver provides its  */
+#define FT_MODULE_DRIVER_HAS_HINTER    0x400  /* the driver provides its  */
                                               /* own hinter               */
+#define FT_MODULE_DRIVER_HINTS_LIGHTLY 0x800  /* the driver's hinter      */
+                                              /* produces LIGHT hints     */
 
 
   /* deprecated values */
@@ -125,9 +127,10 @@
 #define ft_module_hinter              FT_MODULE_HINTER
 #define ft_module_styler              FT_MODULE_STYLER
 
-#define ft_module_driver_scalable     FT_MODULE_DRIVER_SCALABLE
-#define ft_module_driver_no_outlines  FT_MODULE_DRIVER_NO_OUTLINES
-#define ft_module_driver_has_hinter   FT_MODULE_DRIVER_HAS_HINTER
+#define ft_module_driver_scalable       FT_MODULE_DRIVER_SCALABLE
+#define ft_module_driver_no_outlines    FT_MODULE_DRIVER_NO_OUTLINES
+#define ft_module_driver_has_hinter     FT_MODULE_DRIVER_HAS_HINTER
+#define ft_module_driver_hints_lightly  FT_MODULE_DRIVER_HINTS_LIGHTLY
 
 
   typedef FT_Pointer  FT_Module_Interface;
@@ -610,12 +613,7 @@
    *       The library doesn't implement any kind of bytecode interpreter.
    *
    *     FT_TRUETYPE_ENGINE_TYPE_UNPATENTED ::
-   *       The library implements a bytecode interpreter that doesn't
-   *       support the patented operations of the TrueType virtual machine.
-   *
-   *       Its main use is to load certain Asian fonts that position and
-   *       scale glyph components with bytecode instructions.  It produces
-   *       bad output for most other fonts.
+   *       Deprecated and removed.
    *
    *     FT_TRUETYPE_ENGINE_TYPE_PATENTED ::
    *       The library implements a bytecode interpreter that covers
@@ -663,7 +661,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTMODAPI_H__ */
+#endif /* FTMODAPI_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftmoderr.h b/third_party/freetype/include/freetype/ftmoderr.h
index 9d7f981..7f60837 100644
--- a/third_party/freetype/include/freetype/ftmoderr.h
+++ b/third_party/freetype/include/freetype/ftmoderr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType module error offsets (specification).                       */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -74,7 +74,7 @@
   /* with something like                                                   */
   /*                                                                       */
   /*   {                                                                   */
-  /*     #undef __FTMODERR_H__                                             */
+  /*     #undef FTMODERR_H_                                                */
   /*     #define FT_MODERRDEF( e, v, s )  { FT_Mod_Err_ ## e, s },         */
   /*     #define FT_MODERR_START_LIST     {                                */
   /*     #define FT_MODERR_END_LIST       { 0, 0 } };                      */
@@ -91,8 +91,8 @@
   /*************************************************************************/
 
 
-#ifndef __FTMODERR_H__
-#define __FTMODERR_H__
+#ifndef FTMODERR_H_
+#define FTMODERR_H_
 
 
   /*******************************************************************/
@@ -188,7 +188,7 @@
 #undef FT_NEED_EXTERN_C
 
 
-#endif /* __FTMODERR_H__ */
+#endif /* FTMODERR_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftotval.h b/third_party/freetype/include/freetype/ftotval.h
index e744b71..b5d27cf 100644
--- a/third_party/freetype/include/freetype/ftotval.h
+++ b/third_party/freetype/include/freetype/ftotval.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for validating OpenType tables (specification).         */
 /*                                                                         */
-/*  Copyright 2004-2015 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,       */
@@ -27,8 +27,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTOTVAL_H__
-#define __FTOTVAL_H__
+#ifndef FTOTVAL_H_
+#define FTOTVAL_H_
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
@@ -106,12 +106,12 @@
 #define FT_VALIDATE_JSTF  0x1000
 #define FT_VALIDATE_MATH  0x2000
 
-#define FT_VALIDATE_OT  FT_VALIDATE_BASE | \
-                        FT_VALIDATE_GDEF | \
-                        FT_VALIDATE_GPOS | \
-                        FT_VALIDATE_GSUB | \
-                        FT_VALIDATE_JSTF | \
-                        FT_VALIDATE_MATH
+#define FT_VALIDATE_OT  ( FT_VALIDATE_BASE | \
+                          FT_VALIDATE_GDEF | \
+                          FT_VALIDATE_GPOS | \
+                          FT_VALIDATE_GSUB | \
+                          FT_VALIDATE_JSTF | \
+                          FT_VALIDATE_MATH )
 
  /**********************************************************************
   *
@@ -198,7 +198,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTOTVAL_H__ */
+#endif /* FTOTVAL_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftoutln.h b/third_party/freetype/include/freetype/ftoutln.h
index b6ec70d..07f73eb 100644
--- a/third_party/freetype/include/freetype/ftoutln.h
+++ b/third_party/freetype/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-2015 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,       */
@@ -17,8 +17,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTOUTLN_H__
-#define __FTOUTLN_H__
+#ifndef FTOUTLN_H_
+#define FTOUTLN_H_
 
 
 #include <ft2build.h>
@@ -115,6 +115,10 @@
   /*    outline for stroking purposes (otherwise it would result in a      */
   /*    visible dot when round caps are used).                             */
   /*                                                                       */
+  /*    Similarly, the function returns success for an empty outline also  */
+  /*    (doing nothing, this is, not calling any emitter); if necessary,   */
+  /*    you should filter this out, too.                                   */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Outline_Decompose( FT_Outline*              outline,
                         const FT_Outline_Funcs*  func_interface,
@@ -213,6 +217,10 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0~means success.                             */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    An empty outline, or an outline with a single point only is also   */
+  /*    valid.                                                             */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Outline_Check( FT_Outline*  outline );
 
@@ -563,7 +571,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTOUTLN_H__ */
+#endif /* FTOUTLN_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftrender.h b/third_party/freetype/include/freetype/ftrender.h
index ec8da70..9608375 100644
--- a/third_party/freetype/include/freetype/ftrender.h
+++ b/third_party/freetype/include/freetype/ftrender.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType renderer modules public interface (specification).          */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTRENDER_H__
-#define __FTRENDER_H__
+#ifndef FTRENDER_H_
+#define FTRENDER_H_
 
 
 #include <ft2build.h>
@@ -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;
@@ -226,7 +227,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTRENDER_H__ */
+#endif /* FTRENDER_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftsizes.h b/third_party/freetype/include/freetype/ftsizes.h
index bef8424..2f3958a 100644
--- a/third_party/freetype/include/freetype/ftsizes.h
+++ b/third_party/freetype/include/freetype/ftsizes.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType size objects management (specification).                    */
 /*                                                                         */
-/*  Copyright 1996-2015 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,8 +25,8 @@
   /*************************************************************************/
 
 
-#ifndef __FTSIZES_H__
-#define __FTSIZES_H__
+#ifndef FTSIZES_H_
+#define FTSIZES_H_
 
 
 #include <ft2build.h>
@@ -153,7 +153,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTSIZES_H__ */
+#endif /* FTSIZES_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftsnames.h b/third_party/freetype/include/freetype/ftsnames.h
index 0f7fbe1..f6daf8c 100644
--- a/third_party/freetype/include/freetype/ftsnames.h
+++ b/third_party/freetype/include/freetype/ftsnames.h
@@ -7,7 +7,7 @@
 /*                                                                         */
 /*    This is _not_ used to retrieve glyph names!                          */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -19,8 +19,8 @@
 /***************************************************************************/
 
 
-#ifndef __FT_SFNT_NAMES_H__
-#define __FT_SFNT_NAMES_H__
+#ifndef FTSNAMES_H_
+#define FTSNAMES_H_
 
 
 #include <ft2build.h>
@@ -147,8 +147,8 @@
   /*                                                                       */
   /* <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       */
@@ -194,7 +194,7 @@
 
 FT_END_HEADER
 
-#endif /* __FT_SFNT_NAMES_H__ */
+#endif /* FTSNAMES_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftsynth.h b/third_party/freetype/include/freetype/ftsynth.h
index fbcbad8..1863fa2 100644
--- a/third_party/freetype/include/freetype/ftsynth.h
+++ b/third_party/freetype/include/freetype/ftsynth.h
@@ -5,7 +5,7 @@
 /*    FreeType synthesizing code for emboldening and slanting              */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2000-2015 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,       */
@@ -41,8 +41,8 @@
   /* adapted to the particular needs.                               */
 
 
-#ifndef __FTSYNTH_H__
-#define __FTSYNTH_H__
+#ifndef FTSYNTH_H_
+#define FTSYNTH_H_
 
 
 #include <ft2build.h>
@@ -78,7 +78,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTSYNTH_H__ */
+#endif /* FTSYNTH_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftsystem.h b/third_party/freetype/include/freetype/ftsystem.h
index 2bc9999..1aa4762 100644
--- a/third_party/freetype/include/freetype/ftsystem.h
+++ b/third_party/freetype/include/freetype/ftsystem.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType low-level system interface definition (specification).      */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTSYSTEM_H__
-#define __FTSYSTEM_H__
+#ifndef FTSYSTEM_H_
+#define FTSYSTEM_H_
 
 
 #include <ft2build.h>
@@ -290,7 +290,7 @@
    *     The stream size in bytes.
    *
    *     In case of compressed streams where the size is unknown before
-   *     actually doing the decompression, the value is set to 0x7FFFFFFF. 
+   *     actually doing the decompression, the value is set to 0x7FFFFFFF.
    *     (Note that this size value can occur for normal streams also; it is
    *     thus just a hint.)
    *
@@ -349,7 +349,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTSYSTEM_H__ */
+#endif /* FTSYSTEM_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/fttrigon.h b/third_party/freetype/include/freetype/fttrigon.h
index 485ec51..89f0350 100644
--- a/third_party/freetype/include/freetype/fttrigon.h
+++ b/third_party/freetype/include/freetype/fttrigon.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType trigonometric functions (specification).                    */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTTRIGON_H__
-#define __FTTRIGON_H__
+#ifndef FTTRIGON_H_
+#define FTTRIGON_H_
 
 #include FT_FREETYPE_H
 
@@ -344,7 +344,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTTRIGON_H__ */
+#endif /* FTTRIGON_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ftttdrv.h b/third_party/freetype/include/freetype/ftttdrv.h
index dc0081a..a7b937f 100644
--- a/third_party/freetype/include/freetype/ftttdrv.h
+++ b/third_party/freetype/include/freetype/ftttdrv.h
@@ -5,7 +5,7 @@
 /*    FreeType API for controlling the TrueType driver                     */
 /*    (specification only).                                                */
 /*                                                                         */
-/*  Copyright 2013-2015 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,       */
@@ -17,8 +17,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTTTDRV_H__
-#define __FTTTDRV_H__
+#ifndef FTTTDRV_H_
+#define FTTTDRV_H_
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
@@ -138,31 +138,37 @@
    *   interpreter-version
    *
    * @description:
-   *   Currently, two versions are available, representing the bytecode
-   *   interpreter with and without subpixel hinting support,
-   *   respectively.  The default is subpixel support if
-   *   TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel
-   *   support otherwise (since it isn't available then).
+
+   *   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
+   *   one without, respectively.  The default is subpixel support if
+   *   TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel support
+   *   otherwise (since it isn't available then).
    *
    *   If subpixel hinting is on, many TrueType bytecode instructions behave
    *   differently compared to B/W or grayscale rendering (except if `native
-   *   ClearType' is selected by the font).  The main idea is to render at a
-   *   much increased horizontal resolution, then sampling down the created
-   *   output to subpixel precision.  However, many older fonts are not
-   *   suited to this and must be specially taken care of by applying
-   *   (hardcoded) font-specific tweaks.
+   *   ClearType' is selected by the font).  Microsoft's main idea is to
+   *   render at a much increased horizontal resolution, then sampling down
+   *   the created output to subpixel precision.  However, many older fonts
+   *   are not suited to this and must be specially taken care of by
+   *   applying (hardcoded) tweaks in Microsoft's interpreter.
    *
    *   Details on subpixel hinting and some of the necessary tweaks can be
    *   found in Greg Hitchcock's whitepaper at
-   *   `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'.
+   *   `http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. 
+   *   Note that FreeType currently doesn't really `subpixel hint' (6x1, 6x2,
+   *   or 6x5 supersampling) like discussed in the paper.  Depending on the
+   *   chosen interpreter, it simply ignores instructions on vertical stems
+   *   to arrive at very similar results.
    *
-   *   The following example code demonstrates how to activate subpixel
+   *   The following example code demonstrates how to deactivate subpixel
    *   hinting (omitting the error handling).
    *
    *   {
    *     FT_Library  library;
    *     FT_Face     face;
-   *     FT_UInt     interpreter_version = TT_INTERPRETER_VERSION_38;
+   *     FT_UInt     interpreter_version = TT_INTERPRETER_VERSION_35;
    *
    *
    *     FT_Init_FreeType( &library );
@@ -175,6 +181,8 @@
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
+   *   This property can be set via the `FREETYPE_PROPERTIES' environment
+   *   variable (using values `35', `38', or `40').
    */
 
 
@@ -197,9 +205,19 @@
    *
    *   TT_INTERPRETER_VERSION_38 ::
    *     Version~38 corresponds to MS rasterizer v.1.9; it is roughly
-   *     equivalent to the hinting provided by DirectWrite ClearType (as
-   *     can be found, for example, in the Internet Explorer~9 running on
-   *     Windows~7).
+   *     equivalent to the hinting provided by DirectWrite ClearType (as can
+   *     be found, for example, in the Internet Explorer~9 running on
+   *     Windows~7).  It is used in FreeType to select the `Infinality'
+   *     subpixel hinting code.  The code may be removed in a future
+   *     version.
+   *
+   *   TT_INTERPRETER_VERSION_40 ::
+   *     Version~40 corresponds to MS rasterizer v.2.1; it is roughly
+   *     equivalent to the hinting provided by DirectWrite ClearType (as can
+   *     be found, for example, in Microsoft's Edge Browser on Windows~10). 
+   *     It is used in FreeType to select the `minimal' subpixel hinting
+   *     code, a stripped-down and higher performance version of the
+   *     `Infinality' code.
    *
    * @note:
    *   This property controls the behaviour of the bytecode interpreter
@@ -207,9 +225,9 @@
    *   get rasterized!  In particular, it does not control subpixel color
    *   filtering.
    *
-   *   If FreeType has not been compiled with configuration option
-   *   FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 causes an
-   *   `FT_Err_Unimplemented_Feature' error.
+   *   If FreeType has not been compiled with the configuration option
+   *   FT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 or~40 causes
+   *   an `FT_Err_Unimplemented_Feature' error.
    *
    *   Depending on the graphics framework, Microsoft uses different
    *   bytecode and rendering engines.  As a consequence, the version
@@ -290,13 +308,14 @@
    *   the version~1 gasp table exclusively (like Color ClearType), while
    *   v1.6 only respects the values of version~0 (bits 0 and~1).
    *
-   *   FreeType doesn't provide all capabilities of the most recent
-   *   ClearType incarnation, thus we identify our subpixel support as
-   *   version~38.
+   *   Keep in mind that the features of the above interpreter versions
+   *   might not map exactly to FreeType features or behavior because it is
+   *   a fundamentally different library with different internals.
    *
    */
 #define TT_INTERPRETER_VERSION_35  35
 #define TT_INTERPRETER_VERSION_38  38
+#define TT_INTERPRETER_VERSION_40  40
 
  /* */
 
@@ -304,7 +323,7 @@
 FT_END_HEADER
 
 
-#endif /* __FTTTDRV_H__ */
+#endif /* FTTTDRV_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/fttypes.h b/third_party/freetype/include/freetype/fttypes.h
index 706a1be..eab8ada 100644
--- a/third_party/freetype/include/freetype/fttypes.h
+++ b/third_party/freetype/include/freetype/fttypes.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType simple types definitions (specification only).              */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTTYPES_H__
-#define __FTTYPES_H__
+#ifndef FTTYPES_H_
+#define FTTYPES_H_
 
 
 #include <ft2build.h>
@@ -596,7 +596,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTTYPES_H__ */
+#endif /* FTTYPES_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/autohint.h b/third_party/freetype/include/freetype/internal/autohint.h
index 8d5a977..bae83e7 100644
--- a/third_party/freetype/include/freetype/internal/autohint.h
+++ b/third_party/freetype/include/freetype/internal/autohint.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level `autohint' module-specific interface (specification).     */
 /*                                                                         */
-/*  Copyright 1996-2015 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,8 +24,8 @@
   /*************************************************************************/
 
 
-#ifndef __AUTOHINT_H__
-#define __AUTOHINT_H__
+#ifndef AUTOHINT_H_
+#define AUTOHINT_H_
 
 
   /*************************************************************************/
@@ -238,7 +238,7 @@
 
 FT_END_HEADER
 
-#endif /* __AUTOHINT_H__ */
+#endif /* AUTOHINT_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/ftcalc.h b/third_party/freetype/include/freetype/internal/ftcalc.h
index 67ade7e..c9ac9d8 100644
--- a/third_party/freetype/include/freetype/internal/ftcalc.h
+++ b/third_party/freetype/include/freetype/internal/ftcalc.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Arithmetic computations (specification).                             */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTCALC_H__
-#define __FTCALC_H__
+#ifndef FTCALC_H_
+#define FTCALC_H_
 
 
 #include <ft2build.h>
@@ -47,7 +47,7 @@
   FT_MulFix_arm( FT_Int32  a,
                  FT_Int32  b )
   {
-    register FT_Int32  t, t2;
+    FT_Int32  t, t2;
 
 
     __asm
@@ -80,7 +80,7 @@
   FT_MulFix_arm( FT_Int32  a,
                  FT_Int32  b )
   {
-    register FT_Int32  t, t2;
+    FT_Int32  t, t2;
 
 
     __asm__ __volatile__ (
@@ -116,7 +116,7 @@
   FT_MulFix_i386( FT_Int32  a,
                   FT_Int32  b )
   {
-    register FT_Int32  result;
+    FT_Int32  result;
 
 
     __asm__ __volatile__ (
@@ -152,7 +152,7 @@
   FT_MulFix_i386( FT_Int32  a,
                   FT_Int32  b )
   {
-    register FT_Int32  result;
+    FT_Int32  result;
 
     __asm
     {
@@ -412,7 +412,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTCALC_H__ */
+#endif /* FTCALC_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/ftdebug.h b/third_party/freetype/include/freetype/internal/ftdebug.h
index 216c730..5dcd2b1 100644
--- a/third_party/freetype/include/freetype/internal/ftdebug.h
+++ b/third_party/freetype/include/freetype/internal/ftdebug.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Debugging and logging component (specification).                     */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -21,8 +21,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTDEBUG_H__
-#define __FTDEBUG_H__
+#ifndef FTDEBUG_H_
+#define FTDEBUG_H_
 
 
 #include <ft2build.h>
@@ -249,7 +249,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTDEBUG_H__ */
+#endif /* FTDEBUG_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/ftdriver.h b/third_party/freetype/include/freetype/internal/ftdriver.h
index 16856d3..e82fa8d 100644
--- a/third_party/freetype/include/freetype/internal/ftdriver.h
+++ b/third_party/freetype/include/freetype/internal/ftdriver.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType font driver interface (specification).                      */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTDRIVER_H__
-#define __FTDRIVER_H__
+#ifndef FTDRIVER_H_
+#define FTDRIVER_H_
 
 
 #include <ft2build.h>
@@ -67,15 +67,6 @@
                        FT_Int32      load_flags );
 
 
-  typedef FT_UInt
-  (*FT_CharMap_CharIndexFunc)( FT_CharMap  charmap,
-                               FT_Long     charcode );
-
-  typedef FT_Long
-  (*FT_CharMap_CharNextFunc)( FT_CharMap  charmap,
-                              FT_Long     charcode );
-
-
   typedef FT_Error
   (*FT_Face_GetKerningFunc)( FT_Face     face,
                              FT_UInt     left_glyph,
@@ -213,7 +204,7 @@
   /*    And when it is no longer needed a `destroy' function needs to be   */
   /*    called to release that allocation.                                 */
   /*                                                                       */
-  /*    `fcinit.c' (ft_create_default_module_classes) already contains a   */
+  /*    `ftinit.c' (ft_create_default_module_classes) already contains a   */
   /*    mechanism to call these functions for the default modules          */
   /*    described in `ftmodule.h'.                                         */
   /*                                                                       */
@@ -403,7 +394,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTDRIVER_H__ */
+#endif /* FTDRIVER_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/ftgloadr.h b/third_party/freetype/include/freetype/internal/ftgloadr.h
index 970dd70..f41c3df 100644
--- a/third_party/freetype/include/freetype/internal/ftgloadr.h
+++ b/third_party/freetype/include/freetype/internal/ftgloadr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph loader (specification).                           */
 /*                                                                         */
-/*  Copyright 2002-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTGLOADR_H__
-#define __FTGLOADR_H__
+#ifndef FTGLOADR_H_
+#define FTGLOADR_H_
 
 
 #include <ft2build.h>
@@ -36,24 +36,6 @@
   /*    The glyph loader is an internal object used to load several glyphs */
   /*    together (for example, in the case of composites).                 */
   /*                                                                       */
-  /* <Note>                                                                */
-  /*    The glyph loader implementation is not part of the high-level API, */
-  /*    hence the forward structure declaration.                           */
-  /*                                                                       */
-  typedef struct FT_GlyphLoaderRec_*  FT_GlyphLoader ;
-
-
-#if 0  /* moved to freetype.h in version 2.2 */
-#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS          1
-#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES      2
-#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID        4
-#define FT_SUBGLYPH_FLAG_SCALE                   8
-#define FT_SUBGLYPH_FLAG_XY_SCALE             0x40
-#define FT_SUBGLYPH_FLAG_2X2                  0x80
-#define FT_SUBGLYPH_FLAG_USE_MY_METRICS      0x200
-#endif
-
-
   typedef struct  FT_SubGlyphRec_
   {
     FT_Int     index;
@@ -89,7 +71,7 @@
 
     void*            other;            /* for possible future extension? */
 
-  } FT_GlyphLoaderRec;
+  } FT_GlyphLoaderRec, *FT_GlyphLoader;
 
 
   /* create new empty glyph loader */
@@ -166,7 +148,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTGLOADR_H__ */
+#endif /* FTGLOADR_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/fthash.h b/third_party/freetype/include/freetype/internal/fthash.h
new file mode 100644
index 0000000..f22f9d5
--- /dev/null
+++ b/third_party/freetype/include/freetype/internal/fthash.h
@@ -0,0 +1,136 @@
+/***************************************************************************/
+/*                                                                         */
+/*  fthash.h                                                               */
+/*                                                                         */
+/*    Hashing functions (specification).                                   */
+/*                                                                         */
+/***************************************************************************/
+
+/*
+ * Copyright 2000 Computing Research Labs, New Mexico State University
+ * Copyright 2001-2015
+ *   Francesco Zappa Nardelli
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
+ * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50     */
+  /*                                                                       */
+  /*  taken from Mark Leisher's xmbdfed package                            */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef FTHASH_H_
+#define FTHASH_H_
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+
+FT_BEGIN_HEADER
+
+
+  typedef union  FT_Hashkey_
+  {
+    FT_Int       num;
+    const char*  str;
+
+  } FT_Hashkey;
+
+
+  typedef struct  FT_HashnodeRec_
+  {
+    FT_Hashkey  key;
+    size_t      data;
+
+  } FT_HashnodeRec;
+
+  typedef struct FT_HashnodeRec_  *FT_Hashnode;
+
+
+  typedef FT_ULong
+  (*FT_Hash_LookupFunc)( FT_Hashkey*  key );
+
+  typedef FT_Bool
+  (*FT_Hash_CompareFunc)( FT_Hashkey*  a,
+                          FT_Hashkey*  b );
+
+
+  typedef struct  FT_HashRec_
+  {
+    FT_UInt  limit;
+    FT_UInt  size;
+    FT_UInt  used;
+
+    FT_Hash_LookupFunc   lookup;
+    FT_Hash_CompareFunc  compare;
+
+    FT_Hashnode*  table;
+
+  } FT_HashRec;
+
+  typedef struct FT_HashRec_  *FT_Hash;
+
+
+  FT_Error
+  ft_hash_str_init( FT_Hash    hash,
+                    FT_Memory  memory );
+
+  FT_Error
+  ft_hash_num_init( FT_Hash    hash,
+                    FT_Memory  memory );
+
+  void
+  ft_hash_str_free( FT_Hash    hash,
+                    FT_Memory  memory );
+
+#define ft_hash_num_free  ft_hash_str_free
+
+  FT_Error
+  ft_hash_str_insert( const char*  key,
+                      size_t       data,
+                      FT_Hash      hash,
+                      FT_Memory    memory );
+
+  FT_Error
+  ft_hash_num_insert( FT_Int     num,
+                      size_t     data,
+                      FT_Hash    hash,
+                      FT_Memory  memory );
+
+  size_t*
+  ft_hash_str_lookup( const char*  key,
+                      FT_Hash      hash );
+
+  size_t*
+  ft_hash_num_lookup( FT_Int   num,
+                      FT_Hash  hash );
+
+
+FT_END_HEADER
+
+
+#endif /* FTHASH_H_ */
+
+
+/* END */
diff --git a/third_party/freetype/include/freetype/internal/ftmemory.h b/third_party/freetype/include/freetype/internal/ftmemory.h
index c0c553b..59e5b58 100644
--- a/third_party/freetype/include/freetype/internal/ftmemory.h
+++ b/third_party/freetype/include/freetype/internal/ftmemory.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType memory management macros (specification).               */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTMEMORY_H__
-#define __FTMEMORY_H__
+#ifndef FTMEMORY_H_
+#define FTMEMORY_H_
 
 
 #include <ft2build.h>
@@ -65,13 +65,15 @@
 
 #ifdef __cplusplus
 
-  extern "C++"
+extern "C++"
+{
   template <typename T> inline T*
   cplusplus_typeof(        T*,
                     void  *v )
   {
     return static_cast <T*> ( v );
   }
+}
 
 #define FT_ASSIGNP( p, val )  (p) = cplusplus_typeof( (p), (val) )
 
@@ -106,10 +108,12 @@
 
   /*
    *  The allocation functions return a pointer, and the error code
-   *  is written to through the `p_error' parameter.  See below for
-   *  for documentation.
+   *  is written to through the `p_error' parameter.
    */
 
+  /* The `q' variants of the functions below (`q' for `quick') don't fill */
+  /* the allocated or reallocated memory with zero bytes.                 */
+
   FT_BASE( FT_Pointer )
   ft_mem_alloc( FT_Memory  memory,
                 FT_Long    size,
@@ -141,6 +145,9 @@
                const void*  P );
 
 
+  /* The `Q' variants of the macros below (`Q' for `quick') don't fill */
+  /* the allocated or reallocated memory with zero bytes.              */
+
 #define FT_MEM_ALLOC( ptr, size )                               \
           FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory,          \
                                                (FT_Long)(size), \
@@ -380,7 +387,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTMEMORY_H__ */
+#endif /* FTMEMORY_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/ftobjs.h b/third_party/freetype/include/freetype/internal/ftobjs.h
index da5582d..772d82c 100644
--- a/third_party/freetype/include/freetype/internal/ftobjs.h
+++ b/third_party/freetype/include/freetype/internal/ftobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType private base classes (specification).                   */
 /*                                                                         */
-/*  Copyright 1996-2015 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,8 +23,8 @@
   /*************************************************************************/
 
 
-#ifndef __FTOBJS_H__
-#define __FTOBJS_H__
+#ifndef FTOBJS_H_
+#define FTOBJS_H_
 
 #include <ft2build.h>
 #include FT_RENDER_H
@@ -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;
@@ -341,12 +342,6 @@
   /*      this data when first opened.  This field exists only if          */
   /*      @FT_CONFIG_OPTION_INCREMENTAL is defined.                        */
   /*                                                                       */
-  /*    ignore_unpatented_hinter ::                                        */
-  /*      This boolean flag instructs the glyph loader to ignore the       */
-  /*      native font hinter, if one is found.  This is exclusively used   */
-  /*      in the case when the unpatented hinter is compiled within the    */
-  /*      library.                                                         */
-  /*                                                                       */
   /*    refcount ::                                                        */
   /*      A counter initialized to~1 at the time an @FT_Face structure is  */
   /*      created.  @FT_Reference_Face increments this counter, and        */
@@ -365,7 +360,6 @@
     FT_Incremental_InterfaceRec*  incremental_interface;
 #endif
 
-    FT_Bool             ignore_unpatented_hinter;
     FT_Int              refcount;
 
   } FT_Face_InternalRec;
@@ -506,6 +500,9 @@
 #define FT_DRIVER_HAS_HINTER( x )  ( FT_MODULE_CLASS( x )->module_flags & \
                                      FT_MODULE_DRIVER_HAS_HINTER )
 
+#define FT_DRIVER_HINTS_LIGHTLY( x )  ( FT_MODULE_CLASS( x )->module_flags & \
+                                        FT_MODULE_DRIVER_HINTS_LIGHTLY )
+
 
   /*************************************************************************/
   /*                                                                       */
@@ -534,7 +531,16 @@
 
   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 )
+  ft_property_string_set( FT_Library        library,
+                          const FT_String*  module_name,
+                          const FT_String*  property_name,
+                          FT_String*        value );
+#endif
 
   /* */
 
@@ -772,13 +778,6 @@
 #define FT_DEBUG_HOOK_TRUETYPE            0
 
 
-  /* Set this debug hook to a non-null pointer to force unpatented hinting */
-  /* for all faces when both TT_USE_BYTECODE_INTERPRETER and               */
-  /* TT_CONFIG_OPTION_UNPATENTED_HINTING are defined.  This is only used   */
-  /* during debugging.                                                     */
-#define FT_DEBUG_HOOK_UNPATENTED_HINTING  1
-
-
   typedef void  (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap*      bitmap,
                                             FT_Render_Mode  render_mode,
                                             FT_Library      library );
@@ -844,7 +843,7 @@
   /*                        filtering callback function.                   */
   /*                                                                       */
   /*    pic_container    :: Contains global structs and tables, instead    */
-  /*                        of defining them globallly.                    */
+  /*                        of defining them globally.                     */
   /*                                                                       */
   /*    refcount         :: A counter initialized to~1 at the time an      */
   /*                        @FT_Library structure is created.              */
@@ -877,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
 
@@ -982,8 +981,8 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    Used to initialize an instance of FT_Outline_Funcs struct.         */
-  /*    When FT_CONFIG_OPTION_PIC is defined an init funtion will need to  */
-  /*    be called with a pre-allocated structure to be filled.             */
+  /*    When FT_CONFIG_OPTION_PIC is defined an init function will need    */
+  /*    to be called with a pre-allocated structure to be filled.          */
   /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
   /*    allocated in the global scope (or the scope where the macro        */
   /*    is used).                                                          */
@@ -1041,8 +1040,8 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    Used to initialize an instance of FT_Raster_Funcs struct.          */
-  /*    When FT_CONFIG_OPTION_PIC is defined an init funtion will need to  */
-  /*    be called with a pre-allocated structure to be filled.             */
+  /*    When FT_CONFIG_OPTION_PIC is defined an init function will need    */
+  /*    to be called with a pre-allocated structure to be filled.          */
   /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
   /*    allocated in the global scope (or the scope where the macro        */
   /*    is used).                                                          */
@@ -1101,8 +1100,8 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    Used to initialize an instance of FT_Glyph_Class struct.           */
-  /*    When FT_CONFIG_OPTION_PIC is defined an init funtion will need to  */
-  /*    be called with a pre-allocated stcture to be filled.               */
+  /*    When FT_CONFIG_OPTION_PIC is defined an init function will need    */
+  /*    to be called with a pre-allocated structure to be filled.          */
   /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
   /*    allocated in the global scope (or the scope where the macro        */
   /*    is used).                                                          */
@@ -1175,11 +1174,11 @@
   /* <Description>                                                         */
   /*    Used to initialize an instance of FT_Renderer_Class struct.        */
   /*                                                                       */
-  /*    When FT_CONFIG_OPTION_PIC is defined a `create' funtion will need  */
-  /*    to be called with a pointer where the allocated structure is       */
+  /*    When FT_CONFIG_OPTION_PIC is defined a `create' function will      */
+  /*    need to be called with a pointer where the allocated structure is  */
   /*    returned.  And when it is no longer needed a `destroy' function    */
   /*    needs to be called to release that allocation.                     */
-  /*    `fcinit.c' (ft_create_default_module_classes) already contains     */
+  /*    `ftinit.c' (ft_create_default_module_classes) already contains     */
   /*    a mechanism to call these functions for the default modules        */
   /*    described in `ftmodule.h'.                                         */
   /*                                                                       */
@@ -1379,11 +1378,11 @@
   /* <Description>                                                         */
   /*    Used to initialize an instance of an FT_Module_Class struct.       */
   /*                                                                       */
-  /*    When FT_CONFIG_OPTION_PIC is defined a `create' funtion needs to   */
-  /*    be called with a pointer where the allocated structure is          */
+  /*    When FT_CONFIG_OPTION_PIC is defined a `create' function needs     */
+  /*    to be called with a pointer where the allocated structure is       */
   /*    returned.  And when it is no longer needed a `destroy' function    */
   /*    needs to be called to release that allocation.                     */
-  /*    `fcinit.c' (ft_create_default_module_classes) already contains     */
+  /*    `ftinit.c' (ft_create_default_module_classes) already contains     */
   /*    a mechanism to call these functions for the default modules        */
   /*    described in `ftmodule.h'.                                         */
   /*                                                                       */
@@ -1565,7 +1564,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTOBJS_H__ */
+#endif /* FTOBJS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/ftpic.h b/third_party/freetype/include/freetype/internal/ftpic.h
index 7f9154f..0d43ed2 100644
--- a/third_party/freetype/include/freetype/internal/ftpic.h
+++ b/third_party/freetype/include/freetype/internal/ftpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services (declaration).       */
 /*                                                                         */
-/*  Copyright 2009-2015 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -23,8 +23,8 @@
   /*************************************************************************/
 
 
-#ifndef __FTPIC_H__
-#define __FTPIC_H__
+#ifndef FTPIC_H_
+#define FTPIC_H_
 
 
 FT_BEGIN_HEADER
@@ -65,7 +65,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTPIC_H__ */
+#endif /* FTPIC_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/ftrfork.h b/third_party/freetype/include/freetype/internal/ftrfork.h
index da61ca7..25a44a4 100644
--- a/third_party/freetype/include/freetype/internal/ftrfork.h
+++ b/third_party/freetype/include/freetype/internal/ftrfork.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Embedded resource forks accessor (specification).                    */
 /*                                                                         */
-/*  Copyright 2004-2015 by                                                 */
+/*  Copyright 2004-2017 by                                                 */
 /*  Masatake YAMATO and Redhat K.K.                                        */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -21,8 +21,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTRFORK_H__
-#define __FTRFORK_H__
+#ifndef FTRFORK_H_
+#define FTRFORK_H_
 
 
 #include <ft2build.h>
@@ -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,
@@ -227,7 +228,7 @@
   /*    sort_by_res_id ::                                                  */
   /*      A Boolean to sort the fragmented resource by their ids.          */
   /*      The fragmented resources for `POST' resource should be sorted    */
-  /*      to restore Type1 font properly.  For `snft' resources, sorting   */
+  /*      to restore Type1 font properly.  For `sfnt' resources, sorting   */
   /*      may induce a different order of the faces in comparison to that  */
   /*      by QuickDraw API.                                                */
   /*                                                                       */
@@ -260,7 +261,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTRFORK_H__ */
+#endif /* FTRFORK_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/ftserv.h b/third_party/freetype/include/freetype/internal/ftserv.h
index 11a0c7f..c84afba 100644
--- a/third_party/freetype/include/freetype/internal/ftserv.h
+++ b/third_party/freetype/include/freetype/internal/ftserv.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType services (specification only).                          */
 /*                                                                         */
-/*  Copyright 2003-2015 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,       */
@@ -28,8 +28,8 @@
   /*************************************************************************/
 
 
-#ifndef __FTSERV_H__
-#define __FTSERV_H__
+#ifndef FTSERV_H_
+#define FTSERV_H_
 
 
 FT_BEGIN_HEADER
@@ -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,28 @@
     { 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 }                                                          \
+  };
+
 #else /* FT_CONFIG_OPTION_PIC */
 
 #define FT_DEFINE_SERVICEDESCREC1( class_,                                  \
@@ -593,6 +616,62 @@
     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;                                                       \
+  }
+
 #endif /* FT_CONFIG_OPTION_PIC */
 
 
@@ -635,6 +714,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;
@@ -739,6 +819,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>
@@ -757,7 +838,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTSERV_H__ */
+#endif /* FTSERV_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/ftstream.h b/third_party/freetype/include/freetype/internal/ftstream.h
index 384e5df..02b2f0b 100644
--- a/third_party/freetype/include/freetype/internal/ftstream.h
+++ b/third_party/freetype/include/freetype/internal/ftstream.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Stream handling (specification).                                     */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTSTREAM_H__
-#define __FTSTREAM_H__
+#ifndef FTSTREAM_H_
+#define FTSTREAM_H_
 
 
 #include <ft2build.h>
@@ -530,7 +530,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTSTREAM_H__ */
+#endif /* FTSTREAM_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/ftvalid.h b/third_party/freetype/include/freetype/internal/ftvalid.h
index 9cda6ee..df6f7c5 100644
--- a/third_party/freetype/include/freetype/internal/ftvalid.h
+++ b/third_party/freetype/include/freetype/internal/ftvalid.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType validation support (specification).                         */
 /*                                                                         */
-/*  Copyright 2004-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTVALID_H__
-#define __FTVALID_H__
+#ifndef FTVALID_H_
+#define FTVALID_H_
 
 #include <ft2build.h>
 #include FT_CONFIG_STANDARD_LIBRARY_H   /* for ft_setjmp and ft_longjmp */
@@ -153,7 +153,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTVALID_H__ */
+#endif /* FTVALID_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/internal.h b/third_party/freetype/include/freetype/internal/internal.h
index 809ce59..0204681 100644
--- a/third_party/freetype/include/freetype/internal/internal.h
+++ b/third_party/freetype/include/freetype/internal/internal.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Internal header files (specification only).                          */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -30,6 +30,7 @@
 #define FT_INTERNAL_MEMORY_H              <freetype/internal/ftmemory.h>
 #define FT_INTERNAL_DEBUG_H               <freetype/internal/ftdebug.h>
 #define FT_INTERNAL_CALC_H                <freetype/internal/ftcalc.h>
+#define FT_INTERNAL_HASH_H                <freetype/internal/fthash.h>
 #define FT_INTERNAL_DRIVER_H              <freetype/internal/ftdriver.h>
 #define FT_INTERNAL_TRACE_H               <freetype/internal/fttrace.h>
 #define FT_INTERNAL_GLYPH_LOADER_H        <freetype/internal/ftgloadr.h>
@@ -43,7 +44,6 @@
 
 #define FT_INTERNAL_POSTSCRIPT_AUX_H      <freetype/internal/psaux.h>
 #define FT_INTERNAL_POSTSCRIPT_HINTS_H    <freetype/internal/pshints.h>
-#define FT_INTERNAL_POSTSCRIPT_GLOBALS_H  <freetype/internal/psglobal.h>
 
 #define FT_INTERNAL_AUTOHINT_H            <freetype/internal/autohint.h>
 
diff --git a/third_party/freetype/include/freetype/internal/psaux.h b/third_party/freetype/include/freetype/internal/psaux.h
index 1c5f784..286d604 100644
--- a/third_party/freetype/include/freetype/internal/psaux.h
+++ b/third_party/freetype/include/freetype/internal/psaux.h
@@ -5,7 +5,7 @@
 /*    Auxiliary functions and data structures related to PostScript fonts  */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -17,13 +17,14 @@
 /***************************************************************************/
 
 
-#ifndef __PSAUX_H__
-#define __PSAUX_H__
+#ifndef PSAUX_H_
+#define PSAUX_H_
 
 
 #include <ft2build.h>
 #include FT_INTERNAL_OBJECTS_H
 #include FT_INTERNAL_TYPE1_TYPES_H
+#include FT_INTERNAL_HASH_H
 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
 
 
@@ -678,6 +679,7 @@
     FT_Int               num_subrs;
     FT_Byte**            subrs;
     FT_UInt*             subrs_len;    /* array of subrs length (optional) */
+    FT_Hash              subrs_hash;   /* used if `num_subrs' was massaged */
 
     FT_Matrix            font_matrix;
     FT_Vector            font_offset;
@@ -871,7 +873,7 @@
 
 FT_END_HEADER
 
-#endif /* __PSAUX_H__ */
+#endif /* PSAUX_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/pshints.h b/third_party/freetype/include/freetype/internal/pshints.h
index 12aaaba..49116eb 100644
--- a/third_party/freetype/include/freetype/internal/pshints.h
+++ b/third_party/freetype/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-2015 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,       */
@@ -18,8 +18,8 @@
 /***************************************************************************/
 
 
-#ifndef __PSHINTS_H__
-#define __PSHINTS_H__
+#ifndef PSHINTS_H_
+#define PSHINTS_H_
 
 
 #include <ft2build.h>
@@ -716,7 +716,7 @@
 
 FT_END_HEADER
 
-#endif /* __PSHINTS_H__ */
+#endif /* PSHINTS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/services/svcid.h b/third_party/freetype/include/freetype/internal/services/svcid.h
index 4a535a6..cce94d8 100644
--- a/third_party/freetype/include/freetype/internal/services/svcid.h
+++ b/third_party/freetype/include/freetype/internal/services/svcid.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType CID font services (specification).                      */
 /*                                                                         */
-/*  Copyright 2007-2015 by                                                 */
+/*  Copyright 2007-2017 by                                                 */
 /*  Derek Clegg and Michael Toftdal.                                       */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SVCID_H__
-#define __SVCID_H__
+#ifndef SVCID_H_
+#define SVCID_H_
 
 #include FT_INTERNAL_SERVICE_H
 
@@ -84,7 +84,7 @@
 FT_END_HEADER
 
 
-#endif /* __SVCID_H__ */
+#endif /* SVCID_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/services/svfntfmt.h b/third_party/freetype/include/freetype/internal/services/svfntfmt.h
index f8b3617..376d925 100644
--- a/third_party/freetype/include/freetype/internal/services/svfntfmt.h
+++ b/third_party/freetype/include/freetype/internal/services/svfntfmt.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType font format service (specification only).               */
 /*                                                                         */
-/*  Copyright 2003-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SVFNTFMT_H__
-#define __SVFNTFMT_H__
+#ifndef SVFNTFMT_H_
+#define SVFNTFMT_H_
 
 #include FT_INTERNAL_SERVICE_H
 
@@ -49,7 +49,7 @@
 FT_END_HEADER
 
 
-#endif /* __SVFNTFMT_H__ */
+#endif /* SVFNTFMT_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/services/svgldict.h b/third_party/freetype/include/freetype/internal/services/svgldict.h
index f78bca5..0cd1361 100644
--- a/third_party/freetype/include/freetype/internal/services/svgldict.h
+++ b/third_party/freetype/include/freetype/internal/services/svgldict.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph dictionary services (specification).              */
 /*                                                                         */
-/*  Copyright 2003-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SVGLDICT_H__
-#define __SVGLDICT_H__
+#ifndef SVGLDICT_H_
+#define SVGLDICT_H_
 
 #include FT_INTERNAL_SERVICE_H
 
@@ -85,4 +85,7 @@
 FT_END_HEADER
 
 
-#endif /* __SVGLDICT_H__ */
+#endif /* SVGLDICT_H_ */
+
+
+/* END */
diff --git a/third_party/freetype/include/freetype/internal/services/svkern.h b/third_party/freetype/include/freetype/internal/services/svkern.h
index bc26f15..b8344e9 100644
--- a/third_party/freetype/include/freetype/internal/services/svkern.h
+++ b/third_party/freetype/include/freetype/internal/services/svkern.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType Kerning service (specification).                        */
 /*                                                                         */
-/*  Copyright 2006-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SVKERN_H__
-#define __SVKERN_H__
+#ifndef SVKERN_H_
+#define SVKERN_H_
 
 #include FT_INTERNAL_SERVICE_H
 #include FT_TRUETYPE_TABLES_H
@@ -45,7 +45,7 @@
 FT_END_HEADER
 
 
-#endif /* __SVKERN_H__ */
+#endif /* SVKERN_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/services/svmetric.h b/third_party/freetype/include/freetype/internal/services/svmetric.h
new file mode 100644
index 0000000..cac9bf8
--- /dev/null
+++ b/third_party/freetype/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/third_party/freetype/include/freetype/internal/services/svmm.h b/third_party/freetype/include/freetype/internal/services/svmm.h
index f2cecfb..97af1ac 100644
--- a/third_party/freetype/include/freetype/internal/services/svmm.h
+++ b/third_party/freetype/include/freetype/internal/services/svmm.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType Multiple Masters and GX var services (specification).   */
 /*                                                                         */
-/*  Copyright 2003-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SVMM_H__
-#define __SVMM_H__
+#ifndef SVMM_H_
+#define SVMM_H_
 
 #include FT_INTERNAL_SERVICE_H
 
@@ -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 */
@@ -107,7 +152,7 @@
 
 FT_END_HEADER
 
-#endif /* __SVMM_H__ */
+#endif /* SVMM_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/services/svpostnm.h b/third_party/freetype/include/freetype/internal/services/svpostnm.h
index a89f79e..022cdec 100644
--- a/third_party/freetype/include/freetype/internal/services/svpostnm.h
+++ b/third_party/freetype/include/freetype/internal/services/svpostnm.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType PostScript name services (specification).               */
 /*                                                                         */
-/*  Copyright 2003-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SVPOSTNM_H__
-#define __SVPOSTNM_H__
+#ifndef SVPOSTNM_H_
+#define SVPOSTNM_H_
 
 #include FT_INTERNAL_SERVICE_H
 
@@ -75,7 +75,7 @@
 FT_END_HEADER
 
 
-#endif /* __SVPOSTNM_H__ */
+#endif /* SVPOSTNM_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/services/svprop.h b/third_party/freetype/include/freetype/internal/services/svprop.h
index c9f07ce..eb2d4ee 100644
--- a/third_party/freetype/include/freetype/internal/services/svprop.h
+++ b/third_party/freetype/include/freetype/internal/services/svprop.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType property service (specification).                       */
 /*                                                                         */
-/*  Copyright 2012-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SVPROP_H__
-#define __SVPROP_H__
+#ifndef SVPROP_H_
+#define SVPROP_H_
 
 
 FT_BEGIN_HEADER
@@ -29,7 +29,8 @@
   typedef FT_Error
   (*FT_Properties_SetFunc)( FT_Module    module,
                             const char*  property_name,
-                            const void*  value );
+                            const void*  value,
+                            FT_Bool      value_is_string );
 
   typedef FT_Error
   (*FT_Properties_GetFunc)( FT_Module    module,
@@ -75,7 +76,7 @@
 FT_END_HEADER
 
 
-#endif /* __SVPROP_H__ */
+#endif /* SVPROP_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/services/svpscmap.h b/third_party/freetype/include/freetype/internal/services/svpscmap.h
index 66da6e1..b32122e 100644
--- a/third_party/freetype/include/freetype/internal/services/svpscmap.h
+++ b/third_party/freetype/include/freetype/internal/services/svpscmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType PostScript charmap service (specification).             */
 /*                                                                         */
-/*  Copyright 2003-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SVPSCMAP_H__
-#define __SVPSCMAP_H__
+#ifndef SVPSCMAP_H_
+#define SVPSCMAP_H_
 
 #include FT_INTERNAL_OBJECTS_H
 
@@ -171,7 +171,7 @@
 FT_END_HEADER
 
 
-#endif /* __SVPSCMAP_H__ */
+#endif /* SVPSCMAP_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/services/svpsinfo.h b/third_party/freetype/include/freetype/internal/services/svpsinfo.h
index 752a266..0220ce5 100644
--- a/third_party/freetype/include/freetype/internal/services/svpsinfo.h
+++ b/third_party/freetype/include/freetype/internal/services/svpsinfo.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType PostScript info service (specification).                */
 /*                                                                         */
-/*  Copyright 2003-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SVPSINFO_H__
-#define __SVPSINFO_H__
+#ifndef SVPSINFO_H_
+#define SVPSINFO_H_
 
 #include FT_INTERNAL_SERVICE_H
 #include FT_INTERNAL_TYPE1_TYPES_H
@@ -105,7 +105,7 @@
 FT_END_HEADER
 
 
-#endif /* __SVPSINFO_H__ */
+#endif /* SVPSINFO_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/services/svsfnt.h b/third_party/freetype/include/freetype/internal/services/svsfnt.h
index 252ae1c..49d18e4 100644
--- a/third_party/freetype/include/freetype/internal/services/svsfnt.h
+++ b/third_party/freetype/include/freetype/internal/services/svsfnt.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType SFNT table loading service (specification).             */
 /*                                                                         */
-/*  Copyright 2003-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SVSFNT_H__
-#define __SVSFNT_H__
+#ifndef SVSFNT_H_
+#define SVSFNT_H_
 
 #include FT_INTERNAL_SERVICE_H
 #include FT_TRUETYPE_TABLES_H
@@ -97,7 +97,7 @@
 FT_END_HEADER
 
 
-#endif /* __SVSFNT_H__ */
+#endif /* SVSFNT_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/services/svttcmap.h b/third_party/freetype/include/freetype/internal/services/svttcmap.h
index cd95b9a..30f7fee 100644
--- a/third_party/freetype/include/freetype/internal/services/svttcmap.h
+++ b/third_party/freetype/include/freetype/internal/services/svttcmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType TrueType/sfnt cmap extra information service.           */
 /*                                                                         */
-/*  Copyright 2003-2015 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  Masatake YAMATO, Redhat K.K.,                                          */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
@@ -19,8 +19,8 @@
 /* Development of this service is support of
    Information-technology Promotion Agency, Japan. */
 
-#ifndef __SVTTCMAP_H__
-#define __SVTTCMAP_H__
+#ifndef SVTTCMAP_H_
+#define SVTTCMAP_H_
 
 #include FT_INTERNAL_SERVICE_H
 #include FT_TRUETYPE_TABLES_H
@@ -100,7 +100,7 @@
 
 FT_END_HEADER
 
-#endif /* __SVTTCMAP_H__ */
+#endif /* SVTTCMAP_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/services/svtteng.h b/third_party/freetype/include/freetype/internal/services/svtteng.h
index 272ee8c..e4b368a 100644
--- a/third_party/freetype/include/freetype/internal/services/svtteng.h
+++ b/third_party/freetype/include/freetype/internal/services/svtteng.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType TrueType engine query service (specification).          */
 /*                                                                         */
-/*  Copyright 2006-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SVTTENG_H__
-#define __SVTTENG_H__
+#ifndef SVTTENG_H_
+#define SVTTENG_H_
 
 #include FT_INTERNAL_SERVICE_H
 #include FT_MODULE_H
@@ -47,7 +47,7 @@
 FT_END_HEADER
 
 
-#endif /* __SVTTENG_H__ */
+#endif /* SVTTENG_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/services/svttglyf.h b/third_party/freetype/include/freetype/internal/services/svttglyf.h
index f5cb76a..b779305 100644
--- a/third_party/freetype/include/freetype/internal/services/svttglyf.h
+++ b/third_party/freetype/include/freetype/internal/services/svttglyf.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType TrueType glyph service.                                 */
 /*                                                                         */
-/*  Copyright 2007-2015 by                                                 */
+/*  Copyright 2007-2017 by                                                 */
 /*  David Turner.                                                          */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -15,8 +15,8 @@
 /*                                                                         */
 /***************************************************************************/
 
-#ifndef __SVTTGLYF_H__
-#define __SVTTGLYF_H__
+#ifndef SVTTGLYF_H_
+#define SVTTGLYF_H_
 
 #include FT_INTERNAL_SERVICE_H
 #include FT_TRUETYPE_TABLES_H
@@ -63,7 +63,7 @@
 
 FT_END_HEADER
 
-#endif /* __SVTTGLYF_H__ */
+#endif /* SVTTGLYF_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/sfnt.h b/third_party/freetype/include/freetype/internal/sfnt.h
index 30f53bf..348b5a9 100644
--- a/third_party/freetype/include/freetype/internal/sfnt.h
+++ b/third_party/freetype/include/freetype/internal/sfnt.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level `sfnt' driver interface (specification).                  */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SFNT_H__
-#define __SFNT_H__
+#ifndef SFNT_H_
+#define SFNT_H_
 
 
 #include <ft2build.h>
@@ -742,7 +742,7 @@
 
 FT_END_HEADER
 
-#endif /* __SFNT_H__ */
+#endif /* SFNT_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/t1types.h b/third_party/freetype/include/freetype/internal/t1types.h
index 029acc4..b2e35d4 100644
--- a/third_party/freetype/include/freetype/internal/t1types.h
+++ b/third_party/freetype/include/freetype/internal/t1types.h
@@ -5,7 +5,7 @@
 /*    Basic Type1/Type2 type definitions and interface (specification      */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -17,14 +17,15 @@
 /***************************************************************************/
 
 
-#ifndef __T1TYPES_H__
-#define __T1TYPES_H__
+#ifndef T1TYPES_H_
+#define T1TYPES_H_
 
 
 #include <ft2build.h>
 #include FT_TYPE1_TABLES_H
 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
 #include FT_INTERNAL_SERVICE_H
+#include FT_INTERNAL_HASH_H
 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
 
 
@@ -107,6 +108,7 @@
     FT_Int           num_subrs;
     FT_Byte**        subrs;
     FT_UInt*         subrs_len;
+    FT_Hash          subrs_hash;
 
     FT_Int           num_glyphs;
     FT_String**      glyph_names;       /* array of glyph names       */
@@ -249,7 +251,7 @@
 
 FT_END_HEADER
 
-#endif /* __T1TYPES_H__ */
+#endif /* T1TYPES_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/internal/tttypes.h b/third_party/freetype/include/freetype/internal/tttypes.h
index 1507a7c..6af7303 100644
--- a/third_party/freetype/include/freetype/internal/tttypes.h
+++ b/third_party/freetype/include/freetype/internal/tttypes.h
@@ -5,7 +5,7 @@
 /*    Basic SFNT/TrueType type definitions and interface (specification    */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -17,8 +17,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTTYPES_H__
-#define __TTTYPES_H__
+#ifndef TTTYPES_H_
+#define TTTYPES_H_
 
 
 #include <ft2build.h>
@@ -185,7 +185,7 @@
   /*                                                                       */
   /*    CompLength :: Compressed table length (in bytes).                  */
   /*                                                                       */
-  /*    OrigLength :: Unompressed table length (in bytes).                 */
+  /*    OrigLength :: Uncompressed table length (in bytes).                */
   /*                                                                       */
   /*    CheckSum   :: The table checksum.  This value can be ignored.      */
   /*                                                                       */
@@ -1060,6 +1060,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 +1189,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 +1215,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,22 +1240,19 @@
   /*                            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'.                 */
   /*                                                                       */
-  /*    unpatented_hinting   :: If true, use only unpatented methods in    */
-  /*                            the bytecode interpreter.                  */
+  /*    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).           */
@@ -1243,10 +1261,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_
   {
@@ -1291,6 +1388,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
+
 
     /***********************************************************************/
     /*                                                                     */
@@ -1334,10 +1441,6 @@
     /* used to hook the debugger for the `ttdebug' utility.        */
     TT_Interpreter        interpreter;
 
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    /* Use unpatented hinting only. */
-    FT_Bool               unpatented_hinting;
-#endif
 
     /***********************************************************************/
     /*                                                                     */
@@ -1351,18 +1454,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 */
@@ -1378,6 +1484,7 @@
     FT_ULong              sbit_table_size;
     TT_SbitTableType      sbit_table_type;
     FT_UInt               sbit_num_strikes;
+    FT_UInt*              sbit_strike_map;
 
     FT_Byte*              kern_table;
     FT_ULong              kern_table_size;
@@ -1393,12 +1500,18 @@
     FT_ULong              horz_metrics_offset;
     FT_ULong              vert_metrics_offset;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     /* since 2.4.12 */
     FT_ULong              sph_found_func_flags; /* special functions found */
                                                 /* for this face           */
     FT_Bool               sph_compatibility_mode;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
+
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+    /* since 2.7 */
+    FT_ULong              ebdt_start;  /* either `CBDT', `EBDT', or `bdat' */
+    FT_ULong              ebdt_size;
+#endif
 
   } TT_FaceRec;
 
@@ -1492,8 +1605,6 @@
     FT_Vector        pp1;
     FT_Vector        pp2;
 
-    FT_ULong         glyf_offset;
-
     /* the zone where we load our glyphs */
     TT_GlyphZoneRec  base;
     TT_GlyphZoneRec  zone;
@@ -1515,12 +1626,15 @@
     FT_Byte*         cursor;
     FT_Byte*         limit;
 
+    /* since version 2.6.2 */
+    FT_ListRec       composites;
+
   } TT_LoaderRec;
 
 
 FT_END_HEADER
 
-#endif /* __TTTYPES_H__ */
+#endif /* TTTYPES_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/t1tables.h b/third_party/freetype/include/freetype/t1tables.h
index a6ea415..81c9034 100644
--- a/third_party/freetype/include/freetype/t1tables.h
+++ b/third_party/freetype/include/freetype/t1tables.h
@@ -5,7 +5,7 @@
 /*    Basic Type 1/Type 2 tables definitions and interface (specification  */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -17,8 +17,8 @@
 /***************************************************************************/
 
 
-#ifndef __T1TABLES_H__
-#define __T1TABLES_H__
+#ifndef T1TABLES_H_
+#define T1TABLES_H_
 
 
 #include <ft2build.h>
@@ -755,7 +755,7 @@
 
 FT_END_HEADER
 
-#endif /* __T1TABLES_H__ */
+#endif /* T1TABLES_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/ttnameid.h b/third_party/freetype/include/freetype/ttnameid.h
index c9585f2..7da5c45 100644
--- a/third_party/freetype/include/freetype/ttnameid.h
+++ b/third_party/freetype/include/freetype/ttnameid.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType name ID definitions (specification only).                   */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTNAMEID_H__
-#define __TTNAMEID_H__
+#ifndef TTNAMEID_H_
+#define TTNAMEID_H_
 
 
 #include <ft2build.h>
@@ -1231,7 +1231,7 @@
 
 FT_END_HEADER
 
-#endif /* __TTNAMEID_H__ */
+#endif /* TTNAMEID_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/tttables.h b/third_party/freetype/include/freetype/tttables.h
index 1568f40..7a278e2 100644
--- a/third_party/freetype/include/freetype/tttables.h
+++ b/third_party/freetype/include/freetype/tttables.h
@@ -5,7 +5,7 @@
 /*    Basic SFNT/TrueType tables definitions and interface                 */
 /*    (specification only).                                                */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -17,8 +17,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTTABLES_H__
-#define __TTTABLES_H__
+#ifndef TTTABLES_H_
+#define TTTABLES_H_
 
 
 #include <ft2build.h>
@@ -175,6 +175,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,6 +190,11 @@
   /*    short_metrics          :: A pointer into the `hmtx' table.         */
   /*                                                                       */
   /* <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: `caret_Slope_Rise', */
+  /*    `caret_Slope_Run', and `caret_Offset'.                             */
+  /*                                                                       */
   /*    IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should   */
   /*               be identical except for the names of their fields,      */
   /*               which are different.                                    */
@@ -219,7 +226,7 @@
 
     /* The following fields are not defined by the TrueType specification */
     /* but they are used to connect the metrics header to the relevant    */
-    /* `HMTX' table.                                                      */
+    /* `hmtx' table.                                                      */
 
     void*      long_metrics;
     void*      short_metrics;
@@ -297,8 +304,6 @@
   /*                               slope.                                  */
   /*                                                                       */
   /*    caret_Offset            :: The cursor's offset for slanted fonts.  */
-  /*                               This value is `reserved' in vmtx        */
-  /*                               version 1.0.                            */
   /*                                                                       */
   /*    Reserved                :: 8~reserved bytes.                       */
   /*                                                                       */
@@ -309,11 +314,17 @@
   /*                               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>                                                                */
+  /*    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'.                                                */
+  /*                                                                       */
   /*    IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should   */
   /*               be identical except for the names of their fields,      */
   /*               which are different.                                    */
@@ -344,8 +355,8 @@
     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.                                            */
+    /* but they are used to connect the metrics header to the relevant    */
+    /* `hmtx' or `vmtx' table.                                            */
 
     void*      long_metrics;
     void*      short_metrics;
@@ -359,12 +370,22 @@
   /*    TT_OS2                                                             */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure used to model a TrueType OS/2 table.  All fields       */
+  /*    A structure used 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. */
   /*                                                                       */
+  /*    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'.                                               */
+
   typedef struct  TT_OS2_
   {
     FT_UShort  version;                /* 0x0001 - more or 0xFFFF */
@@ -429,11 +450,17 @@
   /*    TT_Postscript                                                      */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure used to model a TrueType PostScript table.  All fields */
+  /*    A structure used to model a TrueType `post' 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.                                 */
   /*                                                                       */
+  /* <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_
   {
     FT_Fixed  FormatType;
@@ -447,7 +474,7 @@
     FT_ULong  maxMemType1;
 
     /* Glyph names follow in the file, but we don't   */
-    /* load them by default.  See the ttpost.c file.  */
+    /* load them by default.  See file `ttpost.c'.    */
 
   } TT_Postscript;
 
@@ -458,7 +485,7 @@
   /*    TT_PCLT                                                            */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure used to model a TrueType PCLT table.  All fields       */
+  /*    A structure used to model a TrueType `PCLT' table.  All fields     */
   /*    comply to the TrueType specification.                              */
   /*                                                                       */
   typedef struct  TT_PCLT_
@@ -488,7 +515,7 @@
   /*    TT_MaxProfile                                                      */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    The maximum profile is a table containing many max values, which   */
+  /*    The maximum profile (`maxp') table contains many max values, which */
   /*    can be used to pre-allocate arrays.  This ensures that no memory   */
   /*    allocation occurs during a glyph load.                             */
   /*                                                                       */
@@ -587,7 +614,7 @@
   /*                                                                       */
   /*    FT_SFNT_HHEA :: To access the font's @TT_HoriHeader structure.     */
   /*                                                                       */
-  /*    FT_SFNT_VHEA :: To access the font's @TT_VertHeader struture.      */
+  /*    FT_SFNT_VHEA :: To access the font's @TT_VertHeader structure.     */
   /*                                                                       */
   /*    FT_SFNT_POST :: To access the font's @TT_Postscript structure.     */
   /*                                                                       */
@@ -823,7 +850,7 @@
 
 FT_END_HEADER
 
-#endif /* __TTTABLES_H__ */
+#endif /* TTTABLES_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/freetype/tttags.h b/third_party/freetype/include/freetype/tttags.h
index 3836c7b..32eb2fd 100644
--- a/third_party/freetype/include/freetype/tttags.h
+++ b/third_party/freetype/include/freetype/tttags.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Tags for TrueType and OpenType tables (specification only).          */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTAGS_H__
-#define __TTAGS_H__
+#ifndef TTAGS_H_
+#define TTAGS_H_
 
 
 #include <ft2build.h>
@@ -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,12 +103,13 @@
 #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' )
 
 
 FT_END_HEADER
 
-#endif /* __TTAGS_H__ */
+#endif /* TTAGS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/include/ft2build.h b/third_party/freetype/include/ft2build.h
index 419b80a..e7d808f 100644
--- a/third_party/freetype/include/ft2build.h
+++ b/third_party/freetype/include/ft2build.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType 2 build and setup macros.                                   */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -31,12 +31,12 @@
   /*************************************************************************/
 
 
-#ifndef __FT2BUILD_H__
-#define __FT2BUILD_H__
+#ifndef FT2BUILD_H_
+#define FT2BUILD_H_
 
 #include <freetype/config/ftheader.h>
 
-#endif /* __FT2BUILD_H__ */
+#endif /* FT2BUILD_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/base/basepic.c b/third_party/freetype/src/base/basepic.c
index 9850ed9..57fb816 100644
--- a/third_party/freetype/src/base/basepic.c
+++ b/third_party/freetype/src/base/basepic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for base.            */
 /*                                                                         */
-/*  Copyright 2009-2015 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/third_party/freetype/src/base/basepic.h b/third_party/freetype/src/base/basepic.h
index c5d7cbf..258d4ce 100644
--- a/third_party/freetype/src/base/basepic.h
+++ b/third_party/freetype/src/base/basepic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for base.            */
 /*                                                                         */
-/*  Copyright 2009-2015 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __BASEPIC_H__
-#define __BASEPIC_H__
+#ifndef BASEPIC_H_
+#define BASEPIC_H_
 
 
 #include FT_INTERNAL_PIC_H
@@ -85,7 +85,7 @@
 
   /* */
 
-#endif /* __BASEPIC_H__ */
+#endif /* BASEPIC_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/base/ftadvanc.c b/third_party/freetype/src/base/ftadvanc.c
index f12908f..1557607 100644
--- a/third_party/freetype/src/base/ftadvanc.c
+++ b/third_party/freetype/src/base/ftadvanc.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Quick computation of advance widths (body).                          */
 /*                                                                         */
-/*  Copyright 2008-2015 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,8 +60,11 @@
    /*  - unscaled load                                             */
    /*  - unhinted load                                             */
    /*  - light-hinted load                                         */
+   /*  - 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( flags )                            \
+#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 )
 
@@ -87,7 +90,7 @@
       return FT_THROW( Invalid_Glyph_Index );
 
     func = face->driver->clazz->get_advances;
-    if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
+    if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) )
     {
       FT_Error  error;
 
@@ -133,7 +136,7 @@
       return FT_Err_Ok;
 
     func = face->driver->clazz->get_advances;
-    if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
+    if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) )
     {
       error = func( face, start, count, flags, padvances );
       if ( !error )
@@ -157,8 +160,8 @@
 
       /* scale from 26.6 to 16.16 */
       padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
-                      ? face->glyph->advance.y << 10
-                      : face->glyph->advance.x << 10;
+                      ? face->glyph->advance.y * 1024
+                      : face->glyph->advance.x * 1024;
     }
 
     return error;
diff --git a/third_party/freetype/src/base/ftbase.c b/third_party/freetype/src/base/ftbase.c
index 253dfb7..993ac72 100644
--- a/third_party/freetype/src/base/ftbase.c
+++ b/third_party/freetype/src/base/ftbase.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Single object library component (body only).                         */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -26,6 +26,7 @@
 #include "ftcalc.c"
 #include "ftdbgmem.c"
 #include "ftgloadr.c"
+#include "fthash.c"
 #include "ftobjs.c"
 #include "ftoutln.c"
 #include "ftrfork.c"
diff --git a/third_party/freetype/src/base/ftbase.h b/third_party/freetype/src/base/ftbase.h
index e37fefa..2072284 100644
--- a/third_party/freetype/src/base/ftbase.h
+++ b/third_party/freetype/src/base/ftbase.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType private functions used in base module (specification).  */
 /*                                                                         */
-/*  Copyright 2008-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTBASE_H__
-#define __FTBASE_H__
+#ifndef FTBASE_H_
+#define FTBASE_H_
 
 
 #include <ft2build.h>
@@ -68,7 +68,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTBASE_H__ */
+#endif /* FTBASE_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/base/ftbitmap.c b/third_party/freetype/src/base/ftbitmap.c
index a54572a..88c88c4 100644
--- a/third_party/freetype/src/base/ftbitmap.c
+++ b/third_party/freetype/src/base/ftbitmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility functions for bitmaps (body).                       */
 /*                                                                         */
-/*  Copyright 2004-2015 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 )
@@ -351,7 +351,7 @@
     }
 
     /* for each row */
-    for ( y = 0; y < bitmap->rows ; y++ )
+    for ( y = 0; y < bitmap->rows; y++ )
     {
       /*
        * Horizontally:
diff --git a/third_party/freetype/src/base/ftcalc.c b/third_party/freetype/src/base/ftcalc.c
index 619a08b..f052550 100644
--- a/third_party/freetype/src/base/ftcalc.c
+++ b/third_party/freetype/src/base/ftcalc.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Arithmetic computations (body).                                      */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -233,7 +233,7 @@
   {
 #ifdef FT_MULFIX_ASSEMBLER
 
-    return FT_MULFIX_ASSEMBLER( a_, b_ );
+    return FT_MULFIX_ASSEMBLER( (FT_Int32)a_, (FT_Int32)b_ );
 
 #else
 
@@ -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/third_party/freetype/src/base/ftdbgmem.c b/third_party/freetype/src/base/ftdbgmem.c
index 6f20313..242246b 100644
--- a/third_party/freetype/src/base/ftdbgmem.c
+++ b/third_party/freetype/src/base/ftdbgmem.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Memory debugger (body).                                              */
 /*                                                                         */
-/*  Copyright 2001-2015 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 );
@@ -367,7 +367,8 @@
         {
           printf(
             "leaked memory block at address %p, size %8ld in (%s:%ld)\n",
-            node->address, node->size,
+            (void*)node->address,
+            node->size,
             FT_FILENAME( node->source->file_name ),
             node->source->line_no );
 
@@ -462,10 +463,10 @@
               (FT_UInt32)( 5 * _ft_debug_lineno );
     pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS];
 
-    for ( ;; )
+    for (;;)
     {
       node = *pnode;
-      if ( node == NULL )
+      if ( !node )
         break;
 
       if ( node->file_name == _ft_debug_file   &&
@@ -476,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" );
 
@@ -544,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;
@@ -716,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 );
@@ -754,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
@@ -798,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 );
@@ -839,9 +840,9 @@
         memory->free    = ft_mem_debug_free;
 
         p = getenv( "FT2_ALLOC_TOTAL_MAX" );
-        if ( p != NULL )
+        if ( p )
         {
-          FT_Long   total_max = ft_atol( p );
+          FT_Long  total_max = ft_strtol( p, NULL, 10 );
 
 
           if ( total_max > 0 )
@@ -852,9 +853,9 @@
         }
 
         p = getenv( "FT2_ALLOC_COUNT_MAX" );
-        if ( p != NULL )
+        if ( p )
         {
-          FT_Long  total_count = ft_atol( p );
+          FT_Long  total_count = ft_strtol( p, NULL, 10 );
 
 
           if ( total_count > 0 )
@@ -865,9 +866,9 @@
         }
 
         p = getenv( "FT2_KEEP_ALIVE" );
-        if ( p != NULL )
+        if ( p )
         {
-          FT_Long  keep_alive = ft_atol( p );
+          FT_Long  keep_alive = ft_strtol( p, NULL, 10 );
 
 
           if ( keep_alive > 0 )
diff --git a/third_party/freetype/src/base/ftfntfmt.c b/third_party/freetype/src/base/ftfntfmt.c
index 98e7431..dcbeba0 100644
--- a/third_party/freetype/src/base/ftfntfmt.c
+++ b/third_party/freetype/src/base/ftfntfmt.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility file for font formats (body).                       */
 /*                                                                         */
-/*  Copyright 2002-2015 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/third_party/freetype/src/base/ftfstype.c b/third_party/freetype/src/base/ftfstype.c
index cd3458f..cec4fb3 100644
--- a/third_party/freetype/src/base/ftfstype.c
+++ b/third_party/freetype/src/base/ftfstype.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility file to access FSType data (body).                  */
 /*                                                                         */
-/*  Copyright 2008-2015 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/third_party/freetype/src/base/ftgloadr.c b/third_party/freetype/src/base/ftgloadr.c
index 7e28638..8134003 100644
--- a/third_party/freetype/src/base/ftgloadr.c
+++ b/third_party/freetype/src/base/ftgloadr.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph loader (body).                                    */
 /*                                                                         */
-/*  Copyright 2002-2015 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/third_party/freetype/src/base/ftglyph.c b/third_party/freetype/src/base/ftglyph.c
index cb7fc37..9bfb330 100644
--- a/third_party/freetype/src/base/ftglyph.c
+++ b/third_party/freetype/src/base/ftglyph.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType convenience functions to handle glyphs (body).              */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -125,23 +125,25 @@
     FT_BitmapGlyph  glyph = (FT_BitmapGlyph)bitmap_glyph;
 
 
-    cbox->xMin = glyph->left << 6;
-    cbox->xMax = cbox->xMin + (FT_Pos)( glyph->bitmap.width << 6 );
-    cbox->yMax = glyph->top << 6;
-    cbox->yMin = cbox->yMax - (FT_Pos)( glyph->bitmap.rows << 6 );
+    cbox->xMin = glyph->left * 64;
+    cbox->xMax = cbox->xMin + (FT_Pos)( glyph->bitmap.width * 64 );
+    cbox->yMax = glyph->top * 64;
+    cbox->yMin = cbox->yMax - (FT_Pos)( glyph->bitmap.rows * 64 );
   }
 
 
-  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   */
   )
 
 
@@ -403,9 +407,9 @@
     if ( error )
       goto Exit;
 
-    /* copy advance while converting it to 16.16 format */
-    glyph->advance.x = slot->advance.x << 10;
-    glyph->advance.y = slot->advance.y << 10;
+    /* copy advance while converting 26.6 to 16.16 format */
+    glyph->advance.x = slot->advance.x * 1024;
+    glyph->advance.y = slot->advance.y * 1024;
 
     /* now import the image from the glyph slot */
     error = clazz->glyph_init( glyph, slot );
@@ -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/third_party/freetype/src/base/fthash.c b/third_party/freetype/src/base/fthash.c
new file mode 100644
index 0000000..21bc8dd
--- /dev/null
+++ b/third_party/freetype/src/base/fthash.c
@@ -0,0 +1,339 @@
+/***************************************************************************/
+/*                                                                         */
+/*  fthash.c                                                               */
+/*                                                                         */
+/*    Hashing functions (body).                                            */
+/*                                                                         */
+/***************************************************************************/
+
+/*
+ * Copyright 2000 Computing Research Labs, New Mexico State University
+ * Copyright 2001-2015
+ *   Francesco Zappa Nardelli
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
+ * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50     */
+  /*                                                                       */
+  /*  taken from Mark Leisher's xmbdfed package                            */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_HASH_H
+#include FT_INTERNAL_MEMORY_H
+
+
+#define INITIAL_HT_SIZE  241
+
+
+  static FT_ULong
+  hash_str_lookup( FT_Hashkey*  key )
+  {
+    const char*  kp  = key->str;
+    FT_ULong     res = 0;
+
+
+    /* Mocklisp hash function. */
+    while ( *kp )
+      res = ( res << 5 ) - res + (FT_ULong)*kp++;
+
+    return res;
+  }
+
+
+  static FT_ULong
+  hash_num_lookup( FT_Hashkey*  key )
+  {
+    FT_ULong  num = (FT_ULong)key->num;
+    FT_ULong  res;
+
+
+    /* Mocklisp hash function. */
+    res = num & 0xFF;
+    res = ( res << 5 ) - res + ( ( num >>  8 ) & 0xFF );
+    res = ( res << 5 ) - res + ( ( num >> 16 ) & 0xFF );
+    res = ( res << 5 ) - res + ( ( num >> 24 ) & 0xFF );
+
+    return res;
+  }
+
+
+  static FT_Bool
+  hash_str_compare( FT_Hashkey*  a,
+                    FT_Hashkey*  b )
+  {
+    if ( a->str[0] == b->str[0]           &&
+         ft_strcmp( a->str, b->str ) == 0 )
+      return 1;
+
+    return 0;
+  }
+
+
+  static FT_Bool
+  hash_num_compare( FT_Hashkey*  a,
+                    FT_Hashkey*  b )
+  {
+    if ( a->num == b->num )
+      return 1;
+
+    return 0;
+  }
+
+
+  static FT_Hashnode*
+  hash_bucket( FT_Hashkey  key,
+               FT_Hash     hash )
+  {
+    FT_ULong      res = 0;
+    FT_Hashnode*  bp  = hash->table;
+    FT_Hashnode*  ndp;
+
+
+    res = (hash->lookup)( &key );
+
+    ndp = bp + ( res % hash->size );
+    while ( *ndp )
+    {
+      if ( (hash->compare)( &(*ndp)->key, &key ) )
+        break;
+
+      ndp--;
+      if ( ndp < bp )
+        ndp = bp + ( hash->size - 1 );
+    }
+
+    return ndp;
+  }
+
+
+  static FT_Error
+  hash_rehash( FT_Hash    hash,
+               FT_Memory  memory )
+  {
+    FT_Hashnode*  obp = hash->table;
+    FT_Hashnode*  bp;
+    FT_Hashnode*  nbp;
+
+    FT_UInt   i, sz = hash->size;
+    FT_Error  error = FT_Err_Ok;
+
+
+    hash->size <<= 1;
+    hash->limit  = hash->size / 3;
+
+    if ( FT_NEW_ARRAY( hash->table, hash->size ) )
+      goto Exit;
+
+    for ( i = 0, bp = obp; i < sz; i++, bp++ )
+    {
+      if ( *bp )
+      {
+        nbp = hash_bucket( (*bp)->key, hash );
+        *nbp = *bp;
+      }
+    }
+
+    FT_FREE( obp );
+
+  Exit:
+    return error;
+  }
+
+
+  static FT_Error
+  hash_init( FT_Hash    hash,
+             FT_Bool    is_num,
+             FT_Memory  memory )
+  {
+    FT_UInt   sz = INITIAL_HT_SIZE;
+    FT_Error  error;
+
+
+    hash->size  = sz;
+    hash->limit = sz / 3;
+    hash->used  = 0;
+
+    if ( is_num )
+    {
+      hash->lookup  = hash_num_lookup;
+      hash->compare = hash_num_compare;
+    }
+    else
+    {
+      hash->lookup  = hash_str_lookup;
+      hash->compare = hash_str_compare;
+    }
+
+    FT_MEM_NEW_ARRAY( hash->table, sz );
+
+    return error;
+  }
+
+
+  FT_Error
+  ft_hash_str_init( FT_Hash    hash,
+                    FT_Memory  memory )
+  {
+    return hash_init( hash, 0, memory );
+  }
+
+
+  FT_Error
+  ft_hash_num_init( FT_Hash    hash,
+                    FT_Memory  memory )
+  {
+    return hash_init( hash, 1, memory );
+  }
+
+
+  void
+  ft_hash_str_free( FT_Hash    hash,
+                    FT_Memory  memory )
+  {
+    if ( hash )
+    {
+      FT_UInt       sz = hash->size;
+      FT_Hashnode*  bp = hash->table;
+      FT_UInt       i;
+
+
+      for ( i = 0; i < sz; i++, bp++ )
+        FT_FREE( *bp );
+
+      FT_FREE( hash->table );
+    }
+  }
+
+
+  /* `ft_hash_num_free' is the same as `ft_hash_str_free' */
+
+
+  static FT_Error
+  hash_insert( FT_Hashkey  key,
+               size_t      data,
+               FT_Hash     hash,
+               FT_Memory   memory )
+  {
+    FT_Hashnode   nn;
+    FT_Hashnode*  bp    = hash_bucket( key, hash );
+    FT_Error      error = FT_Err_Ok;
+
+
+    nn = *bp;
+    if ( !nn )
+    {
+      if ( FT_NEW( nn ) )
+        goto Exit;
+      *bp = nn;
+
+      nn->key  = key;
+      nn->data = data;
+
+      if ( hash->used >= hash->limit )
+      {
+        error = hash_rehash( hash, memory );
+        if ( error )
+          goto Exit;
+      }
+
+      hash->used++;
+    }
+    else
+      nn->data = data;
+
+  Exit:
+    return error;
+  }
+
+
+  FT_Error
+  ft_hash_str_insert( const char*  key,
+                      size_t       data,
+                      FT_Hash      hash,
+                      FT_Memory    memory )
+  {
+    FT_Hashkey  hk;
+
+
+    hk.str = key;
+
+    return hash_insert( hk, data, hash, memory );
+  }
+
+
+  FT_Error
+  ft_hash_num_insert( FT_Int     num,
+                      size_t     data,
+                      FT_Hash    hash,
+                      FT_Memory  memory )
+  {
+    FT_Hashkey  hk;
+
+
+    hk.num = num;
+
+    return hash_insert( hk, data, hash, memory );
+  }
+
+
+  static size_t*
+  hash_lookup( FT_Hashkey  key,
+               FT_Hash     hash )
+  {
+    FT_Hashnode*  np = hash_bucket( key, hash );
+
+
+    return (*np) ? &(*np)->data
+                 : NULL;
+  }
+
+
+  size_t*
+  ft_hash_str_lookup( const char*  key,
+                      FT_Hash      hash )
+  {
+    FT_Hashkey  hk;
+
+
+    hk.str = key;
+
+    return hash_lookup( hk, hash );
+  }
+
+
+  size_t*
+  ft_hash_num_lookup( FT_Int   num,
+                      FT_Hash  hash )
+  {
+    FT_Hashkey  hk;
+
+
+    hk.num = num;
+
+    return hash_lookup( hk, hash );
+  }
+
+
+/* END */
diff --git a/third_party/freetype/src/base/ftinit.c b/third_party/freetype/src/base/ftinit.c
index b65a91d..1c4b76f 100644
--- a/third_party/freetype/src/base/ftinit.c
+++ b/third_party/freetype/src/base/ftinit.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType initialization layer (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -226,6 +226,115 @@
   }
 
 
+#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+
+#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
+   *
+   */
+
+  static void
+  ft_set_default_properties( FT_Library  library )
+  {
+    const char*  env;
+    const char*  p;
+    const char*  q;
+
+    char  module_name[MAX_LENGTH + 1];
+    char  property_name[MAX_LENGTH + 1];
+    char  property_value[MAX_LENGTH + 1];
+
+    int  i;
+
+
+    env = ft_getenv( "FREETYPE_PROPERTIES" );
+    if ( !env )
+      return;
+
+    for ( p = env; *p; p++ )
+    {
+      /* skip leading whitespace and separators */
+      if ( *p == ' ' || *p == '\t' )
+        continue;
+
+      /* read module name, followed by `:' */
+      q = p;
+      for ( i = 0; i < MAX_LENGTH; i++ )
+      {
+        if ( !*p || *p == ':' )
+          break;
+        module_name[i] = *p++;
+      }
+      module_name[i] = '\0';
+
+      if ( !*p || *p != ':' || p == q )
+        break;
+
+      /* read property name, followed by `=' */
+      q = ++p;
+      for ( i = 0; i < MAX_LENGTH; i++ )
+      {
+        if ( !*p || *p == '=' )
+          break;
+        property_name[i] = *p++;
+      }
+      property_name[i] = '\0';
+
+      if ( !*p || *p != '=' || p == q )
+        break;
+
+      /* read property value, followed by whitespace (if any) */
+      q = ++p;
+      for ( i = 0; i < MAX_LENGTH; i++ )
+      {
+        if ( !*p || *p == ' ' || *p == '\t' )
+          break;
+        property_value[i] = *p++;
+      }
+      property_value[i] = '\0';
+
+      if ( !( *p == '\0' || *p == ' ' || *p == '\t' ) || p == q )
+        break;
+
+      /* we completely ignore errors */
+      ft_property_string_set( library,
+                              module_name,
+                              property_name,
+                              property_value );
+    }
+  }
+
+#else
+
+  static void
+  ft_set_default_properties( FT_Library  library )
+  {
+    FT_UNUSED( library );
+  }
+
+#endif
+
+
   /* documentation is in freetype.h */
 
   FT_EXPORT_DEF( FT_Error )
@@ -256,6 +365,8 @@
     else
       FT_Add_Default_Modules( *alibrary );
 
+    ft_set_default_properties( *alibrary );
+
     return error;
   }
 
diff --git a/third_party/freetype/src/base/ftlcdfil.c b/third_party/freetype/src/base/ftlcdfil.c
index ff6f7e9..f8e1709 100644
--- a/third_party/freetype/src/base/ftlcdfil.c
+++ b/third_party/freetype/src/base/ftlcdfil.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for color filtering of subpixel bitmap glyphs (body).   */
 /*                                                                         */
-/*  Copyright 2006-2015 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,       */
@@ -296,6 +296,8 @@
       return FT_THROW( Invalid_Argument );
 
     ft_memcpy( library->lcd_weights, weights, 5 );
+    library->lcd_filter_func = _ft_lcd_filter_fir;
+    library->lcd_extra       = 2;
 
     return FT_Err_Ok;
   }
@@ -305,12 +307,10 @@
   FT_Library_SetLcdFilter( FT_Library    library,
                            FT_LcdFilter  filter )
   {
+    static const FT_Byte  default_filter[5] =
+                            { 0x08, 0x4d, 0x56, 0x4d, 0x08 };
     static const FT_Byte  light_filter[5] =
                             { 0x00, 0x55, 0x56, 0x55, 0x00 };
-    /* the values here sum up to a value larger than 256, */
-    /* providing a cheap gamma correction                 */
-    static const FT_Byte  default_filter[5] =
-                            { 0x10, 0x40, 0x70, 0x40, 0x10 };
 
 
     if ( !library )
@@ -324,25 +324,9 @@
       break;
 
     case FT_LCD_FILTER_DEFAULT:
-#if defined( FT_FORCE_LEGACY_LCD_FILTER )
-
-      library->lcd_filter_func = _ft_lcd_filter_legacy;
-      library->lcd_extra       = 0;
-
-#elif defined( FT_FORCE_LIGHT_LCD_FILTER )
-
-      ft_memcpy( library->lcd_weights, light_filter, 5 );
-      library->lcd_filter_func = _ft_lcd_filter_fir;
-      library->lcd_extra       = 2;
-
-#else
-
       ft_memcpy( library->lcd_weights, default_filter, 5 );
       library->lcd_filter_func = _ft_lcd_filter_fir;
       library->lcd_extra       = 2;
-
-#endif
-
       break;
 
     case FT_LCD_FILTER_LIGHT:
@@ -354,6 +338,7 @@
 #ifdef USE_LEGACY
 
     case FT_LCD_FILTER_LEGACY:
+    case FT_LCD_FILTER_LEGACY1:
       library->lcd_filter_func = _ft_lcd_filter_legacy;
       library->lcd_extra       = 0;
       break;
diff --git a/third_party/freetype/src/base/ftmm.c b/third_party/freetype/src/base/ftmm.c
index 7c012aa..b8db3c5 100644
--- a/third_party/freetype/src/base/ftmm.c
+++ b/third_party/freetype/src/base/ftmm.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Multiple Master font support (body).                                 */
 /*                                                                         */
-/*  Copyright 1996-2015 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,49 @@
                                  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 );
+    }
+
+    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 +243,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 +258,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 +268,26 @@
     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 );
+    }
+
+    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 +304,49 @@
                                 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 );
+    }
+
+    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 +360,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/third_party/freetype/src/base/ftobjs.c b/third_party/freetype/src/base/ftobjs.c
index f0c2e77..59d65e2 100644
--- a/third_party/freetype/src/base/ftobjs.c
+++ b/third_party/freetype/src/base/ftobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType private base classes (body).                            */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -55,7 +55,18 @@
 #pragma warning( disable : 4244 )
 #endif /* _MSC_VER */
 
-  /* it's easiest to include `md5.c' directly */
+  /* It's easiest to include `md5.c' directly.  However, since OpenSSL */
+  /* also provides the same functions, there might be conflicts if     */
+  /* both FreeType and OpenSSL are built as static libraries.  For     */
+  /* this reason, we put the MD5 stuff into the `FT_' namespace.       */
+#define MD5_u32plus  FT_MD5_u32plus
+#define MD5_CTX      FT_MD5_CTX
+#define MD5_Init     FT_MD5_Init
+#define MD5_Update   FT_MD5_Update
+#define MD5_Final    FT_MD5_Final
+
+#undef  HAVE_OPENSSL
+
 #include "md5.c"
 
 #if defined( _MSC_VER )
@@ -68,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 )
@@ -442,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;
   }
 
@@ -630,6 +651,9 @@
       load_flags &= ~FT_LOAD_RENDER;
     }
 
+    if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY )
+      load_flags &= ~FT_LOAD_RENDER;
+
     /*
      * Determine whether we need to auto-hint or not.
      * The general rules are:
@@ -675,8 +699,8 @@
         /* check the size of the `fpgm' and `prep' tables, too --    */
         /* the assumption is that there don't exist real TTFs where  */
         /* both `fpgm' and `prep' tables are missing                 */
-        if ( mode == FT_RENDER_MODE_LIGHT                       ||
-             face->internal->ignore_unpatented_hinter           ||
+        if ( ( mode == FT_RENDER_MODE_LIGHT                   &&
+               !FT_DRIVER_HINTS_LIGHTLY( driver ) )             ||
              ( FT_IS_SFNT( face )                             &&
                ttface->num_locations                          &&
                ttface->max_profile.maxSizeOfInstructions == 0 &&
@@ -1091,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 &&
@@ -1226,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
@@ -1253,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 );
   }
 
 
@@ -1288,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 )
   {
@@ -1304,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,
@@ -1324,7 +1348,7 @@
       return FT_THROW( Invalid_Argument );
 
     *astream = NULL;
-    memory = library->memory;
+    memory   = library->memory;
     if ( FT_NEW( stream ) )
       goto Exit;
 
@@ -1340,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,
@@ -1366,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 );
     }
 
@@ -1384,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
@@ -1407,7 +1431,7 @@
 
   /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */
   /* format too.  Here, since we can't expect that the TrueType font */
-  /* driver is loaded unconditially, we must parse the font by       */
+  /* driver is loaded unconditionally, we must parse the font by     */
   /* ourselves.  We are only interested in the name of the table and */
   /* the offset.                                                     */
 
@@ -1472,6 +1496,7 @@
       if ( face_index >= 0 && pstable_index == face_index )
         return FT_Err_Ok;
     }
+
     return FT_THROW( Table_Missing );
   }
 
@@ -1509,14 +1534,29 @@
     if ( error )
       goto Exit;
 
-    if ( FT_Stream_Seek( stream, pos + offset ) )
+    if ( offset > stream->size )
+    {
+      FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table offset\n" ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+    else if ( length > stream->size - offset )
+    {
+      FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table length\n" ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    error = FT_Stream_Seek( stream, pos + offset );
+    if ( error )
       goto Exit;
 
     if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) )
       goto Exit;
 
     error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length );
-    if ( error ) {
+    if ( error )
+    {
       FT_FREE( sfnt_ps );
       goto Exit;
     }
@@ -1562,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;
@@ -1577,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,
@@ -1590,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;
       }
@@ -1603,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;
 
@@ -1624,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 )
@@ -1645,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;
@@ -1668,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 );
@@ -1680,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;
@@ -1700,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;
@@ -1728,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 );
@@ -1764,8 +1831,8 @@
     FT_Long    face_index_in_resource = 0;
 
 
-    if ( face_index == -1 )
-      face_index = 0;
+    if ( face_index < 0 )
+      face_index = -face_index - 1;
     if ( face_index >= resource_cnt )
       return FT_THROW( Cannot_Open_Resource );
 
@@ -1776,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 );
@@ -1790,7 +1857,8 @@
       goto Exit;
 
     /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */
-    if ( FT_Stream_Seek( stream, flag_offset + 4 ) )
+    error = FT_Stream_Seek( stream, flag_offset + 4 );
+    if ( error )
       goto Exit;
 
     if ( FT_ALLOC( sfnt_data, rlen ) )
@@ -1828,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 )
@@ -1857,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 )
@@ -1890,7 +1958,7 @@
     FT_Long        dlen, offset;
 
 
-    if ( NULL == stream )
+    if ( !stream )
       return FT_THROW( Invalid_Stream_Operation );
 
     error = FT_Stream_Seek( stream, 0 );
@@ -1964,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;
       }
 
@@ -2080,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;
@@ -2090,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' */
 
@@ -2167,11 +2265,13 @@
             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 */
-            if ( FT_Stream_Seek( stream, 0 ) )
+            error = FT_Stream_Seek( stream, 0 );
+            if ( error )
               break;
 
             error = open_face_PS_from_sfnt_stream( library,
@@ -2203,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 ) )
@@ -2285,11 +2389,24 @@
 
 
         if ( bsize->height < 0 )
-          bsize->height = (FT_Short)-bsize->height;
+          bsize->height = -bsize->height;
         if ( bsize->x_ppem < 0 )
-          bsize->x_ppem = (FT_Short)-bsize->x_ppem;
+          bsize->x_ppem = -bsize->x_ppem;
         if ( bsize->y_ppem < 0 )
           bsize->y_ppem = -bsize->y_ppem;
+
+        /* check whether negation actually has worked */
+        if ( bsize->height < 0 || bsize->x_ppem < 0 || bsize->y_ppem < 0 )
+        {
+          FT_TRACE0(( "FT_Open_Face:"
+                      " Invalid bitmap dimensions for stroke %d,"
+                      " now disabled\n", i ));
+          bsize->width  = 0;
+          bsize->height = 0;
+          bsize->size   = 0;
+          bsize->x_ppem = 0;
+          bsize->y_ppem = 0;
+        }
       }
     }
 
@@ -2323,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;
   }
@@ -2589,6 +2719,9 @@
     w = FT_PIX_ROUND( w );
     h = FT_PIX_ROUND( h );
 
+    if ( !w || !h )
+      return FT_THROW( Invalid_Pixel_Size );
+
     for ( i = 0; i < face->num_fixed_sizes; i++ )
     {
       FT_Bitmap_Size*  bsize = face->available_sizes + i;
@@ -2608,6 +2741,8 @@
       }
     }
 
+    FT_TRACE3(( "FT_Match_Size: no matching bitmap strike\n" ));
+
     return FT_THROW( Invalid_Pixel_Size );
   }
 
@@ -3327,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;
@@ -3472,7 +3607,7 @@
       FT_CMap     ucmap = FT_CMAP( face->charmap );
 
 
-      if ( charmap != NULL )
+      if ( charmap )
       {
         FT_CMap  vcmap = FT_CMAP( charmap );
 
@@ -3513,7 +3648,7 @@
       FT_CharMap  charmap = find_variant_selector_charmap( face );
 
 
-      if ( charmap != NULL )
+      if ( charmap )
       {
         FT_CMap  vcmap = FT_CMAP( charmap );
 
@@ -3552,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 );
@@ -3580,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 );
@@ -3614,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 );
@@ -3742,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 );
     }
 
@@ -3766,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 );
@@ -3791,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 );
@@ -3813,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;
@@ -3837,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;
@@ -4156,39 +4291,51 @@
 #undef  FT_COMPONENT
 #define FT_COMPONENT  trace_bitmap
 
-    /* we convert to a single bitmap format for computing the checksum */
-    if ( !error )
+    /*
+     * Computing the MD5 checksum is expensive, unnecessarily distorting a
+     * possible profiling of FreeType if compiled with tracing support.  For
+     * this reason, we execute the following code only if explicitly
+     * requested.
+     */
+
+    /* we use FT_TRACE3 in this block */
+    if ( ft_trace_levels[trace_bitmap] >= 3 )
     {
-      FT_Bitmap  bitmap;
-      FT_Error   err;
-
-
-      FT_Bitmap_Init( &bitmap );
-
-      /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */
-      err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 );
-      if ( !err )
+      /* we convert to a single bitmap format for computing the checksum */
+      if ( !error && slot->bitmap.buffer )
       {
-        MD5_CTX        ctx;
-        unsigned char  md5[16];
-        int            i;
-        unsigned int   rows  = bitmap.rows;
-        unsigned int   pitch = (unsigned int)bitmap.pitch;
+        FT_Bitmap  bitmap;
+        FT_Error   err;
 
 
-        MD5_Init( &ctx );
-        MD5_Update( &ctx, bitmap.buffer, rows * pitch );
-        MD5_Final( md5, &ctx );
+        FT_Bitmap_Init( &bitmap );
 
-        FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n"
-                    "  ",
-                    rows, pitch ));
-        for ( i = 0; i < 16; i++ )
-          FT_TRACE3(( "%02X", md5[i] ));
-        FT_TRACE3(( "\n" ));
+        /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */
+        err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 );
+        if ( !err )
+        {
+          MD5_CTX        ctx;
+          unsigned char  md5[16];
+          int            i;
+          unsigned int   rows  = bitmap.rows;
+          unsigned int   pitch = (unsigned int)bitmap.pitch;
+
+
+          MD5_Init( &ctx );
+          if ( bitmap.buffer )
+            MD5_Update( &ctx, bitmap.buffer, rows * pitch );
+          MD5_Final( md5, &ctx );
+
+          FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n"
+                      "  ",
+                      rows, pitch ));
+          for ( i = 0; i < 16; i++ )
+            FT_TRACE3(( "%02X", md5[i] ));
+          FT_TRACE3(( "\n" ));
+        }
+
+        FT_Bitmap_Done( library, &bitmap );
       }
-
-      FT_Bitmap_Done( library, &bitmap );
     }
 
 #undef  FT_COMPONENT
@@ -4282,7 +4429,7 @@
   {
     FT_Error   error;
     FT_Memory  memory;
-    FT_Module  module;
+    FT_Module  module = NULL;
     FT_UInt    nn;
 
 
@@ -4434,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;
 
@@ -4447,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;
@@ -4464,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;
             }
           }
@@ -4523,7 +4671,8 @@
                   const FT_String*  module_name,
                   const FT_String*  property_name,
                   void*             value,
-                  FT_Bool           set )
+                  FT_Bool           set,
+                  FT_Bool           value_is_string )
   {
     FT_Module*           cur;
     FT_Module*           limit;
@@ -4593,8 +4742,13 @@
       return FT_THROW( Unimplemented_Feature );
     }
 
-    return set ? service->set_property( cur[0], property_name, value )
-               : service->get_property( cur[0], property_name, value );
+    return set ? service->set_property( cur[0],
+                                        property_name,
+                                        value,
+                                        value_is_string )
+               : service->get_property( cur[0],
+                                        property_name,
+                                        value );
   }
 
 
@@ -4610,7 +4764,8 @@
                            module_name,
                            property_name,
                            (void*)value,
-                           TRUE );
+                           TRUE,
+                           FALSE );
   }
 
 
@@ -4626,10 +4781,33 @@
                            module_name,
                            property_name,
                            value,
+                           FALSE,
                            FALSE );
   }
 
 
+#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+
+  /* this variant is used for handling the FREETYPE_PROPERTIES */
+  /* environment variable                                      */
+
+  FT_BASE_DEF( FT_Error )
+  ft_property_string_set( FT_Library        library,
+                          const FT_String*  module_name,
+                          const FT_String*  property_name,
+                          FT_String*        value )
+  {
+    return ft_property_do( library,
+                           module_name,
+                           property_name,
+                           (void*)value,
+                           TRUE,
+                           TRUE );
+  }
+
+#endif
+
+
   /*************************************************************************/
   /*************************************************************************/
   /*************************************************************************/
@@ -4885,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/third_party/freetype/src/base/ftoutln.c b/third_party/freetype/src/base/ftoutln.c
index 35cc9f5..464a066 100644
--- a/third_party/freetype/src/base/ftoutln.c
+++ b/third_party/freetype/src/base/ftoutln.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType outline management (body).                                  */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -42,7 +42,7 @@
 
 
   static
-  const FT_Outline  null_outline = { 0, 0, 0, 0, 0, 0 };
+  const FT_Outline  null_outline = { 0, 0, NULL, NULL, NULL, 0 };
 
 
   /* documentation is in ftoutln.h */
@@ -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:
@@ -415,11 +415,14 @@
     if ( source == target )
       return FT_Err_Ok;
 
-    FT_ARRAY_COPY( target->points, source->points, source->n_points );
+    if ( source->n_points )
+    {
+      FT_ARRAY_COPY( target->points, source->points, source->n_points );
+      FT_ARRAY_COPY( target->tags,   source->tags,   source->n_points );
+    }
 
-    FT_ARRAY_COPY( target->tags, source->tags, source->n_points );
-
-    FT_ARRAY_COPY( target->contours, source->contours, source->n_contours );
+    if ( source->n_contours )
+      FT_ARRAY_COPY( target->contours, source->contours, source->n_contours );
 
     /* copy all flags, except the `FT_OUTLINE_OWNER' one */
     is_owner      = target->flags & FT_OUTLINE_OWNER;
@@ -942,6 +945,9 @@
       l_in = 0;
       last = outline->contours[c];
 
+      /* pacify compiler */
+      in.x = in.y = anchor.x = anchor.y = 0;
+
       /* Counter j cycles though the points; counter i advances only  */
       /* when points are moved; anchor k marks the first moved point. */
       for ( i = last, j = first, k = -1;
@@ -1074,13 +1080,16 @@
       FT_Int  last = outline->contours[c];
 
 
-      v_prev = points[last];
+      v_prev.x = points[last].x >> xshift;
+      v_prev.y = points[last].y >> yshift;
 
       for ( n = first; n <= last; n++ )
       {
-        v_cur = points[n];
-        area += ( ( v_cur.y - v_prev.y ) >> yshift ) *
-                ( ( v_cur.x + v_prev.x ) >> xshift );
+        v_cur.x = points[n].x >> xshift;
+        v_cur.y = points[n].y >> yshift;
+
+        area += ( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x );
+
         v_prev = v_cur;
       }
 
diff --git a/third_party/freetype/src/base/ftpic.c b/third_party/freetype/src/base/ftpic.c
index 6c4b1cd..0f84fdd 100644
--- a/third_party/freetype/src/base/ftpic.c
+++ b/third_party/freetype/src/base/ftpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services (body).              */
 /*                                                                         */
-/*  Copyright 2009-2015 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/third_party/freetype/src/base/ftrfork.c b/third_party/freetype/src/base/ftrfork.c
index c30c766..f7b8137 100644
--- a/third_party/freetype/src/base/ftrfork.c
+++ b/third_party/freetype/src/base/ftrfork.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Embedded resource forks accessor (body).                             */
 /*                                                                         */
-/*  Copyright 2004-2015 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;
@@ -403,7 +460,7 @@
         errors[i] = FT_Err_Ok;
 
       if ( errors[i] )
-        continue ;
+        continue;
 
       errors[i] = (FT_RACCESS_GUESS_TABLE_GET[i].func)( library,
                                                  stream, base_name,
diff --git a/third_party/freetype/src/base/ftsnames.c b/third_party/freetype/src/base/ftsnames.c
index 80304e5..a5b41eb 100644
--- a/third_party/freetype/src/base/ftsnames.c
+++ b/third_party/freetype/src/base/ftsnames.c
@@ -7,7 +7,7 @@
 /*                                                                         */
 /*    This is _not_ used to retrieve glyph names!                          */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -58,7 +58,7 @@
 
 
         /* 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;
diff --git a/third_party/freetype/src/base/ftstream.c b/third_party/freetype/src/base/ftstream.c
index b68f3f8..a3f8c8b 100644
--- a/third_party/freetype/src/base/ftstream.c
+++ b/third_party/freetype/src/base/ftstream.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    I/O stream support (body).                                           */
 /*                                                                         */
-/*  Copyright 2000-2015 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,       */
@@ -778,7 +778,7 @@
 
       case ft_frame_short_be:
       case ft_frame_ushort_be:  /* read a 2-byte big-endian short */
-        value = FT_NEXT_USHORT( cursor) ;
+        value = FT_NEXT_USHORT( cursor );
         sign_shift = 16;
         break;
 
diff --git a/third_party/freetype/src/base/ftsystem.c b/third_party/freetype/src/base/ftsystem.c
index 1938fd8..324f949 100644
--- a/third_party/freetype/src/base/ftsystem.c
+++ b/third_party/freetype/src/base/ftsystem.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    ANSI-specific FreeType low-level system interface (body).            */
 /*                                                                         */
-/*  Copyright 1996-2015 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/third_party/freetype/src/base/fttrigon.c b/third_party/freetype/src/base/fttrigon.c
index 5b24304..7a4d17c 100644
--- a/third_party/freetype/src/base/fttrigon.c
+++ b/third_party/freetype/src/base/fttrigon.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType trigonometric functions (body).                             */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -71,7 +71,8 @@
 
     /* 0x40000000 comes from regression analysis between true */
     /* and CORDIC hypotenuse, so it minimizes the error       */
-    val = (FT_Fixed)( ( (FT_Int64)val * FT_TRIG_SCALE + 0x40000000UL ) >> 32 );
+    val = (FT_Fixed)(
+            ( (FT_UInt64)val * FT_TRIG_SCALE + 0x40000000UL ) >> 32 );
 
     return s < 0 ? -val : val;
   }
diff --git a/third_party/freetype/src/base/fttype1.c b/third_party/freetype/src/base/fttype1.c
index c549382..4d16a63 100644
--- a/third_party/freetype/src/base/fttype1.c
+++ b/third_party/freetype/src/base/fttype1.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility file for PS names support (body).                   */
 /*                                                                         */
-/*  Copyright 2002-2015 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/third_party/freetype/src/base/ftutil.c b/third_party/freetype/src/base/ftutil.c
index f5b72db..dccc209 100644
--- a/third_party/freetype/src/base/ftutil.c
+++ b/third_party/freetype/src/base/ftutil.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility file for memory and list management (body).         */
 /*                                                                         */
-/*  Copyright 2002-2015 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/third_party/freetype/src/cff/cf2arrst.c b/third_party/freetype/src/cff/cf2arrst.c
index 89f3e9f..6796450 100644
--- a/third_party/freetype/src/cff/cf2arrst.c
+++ b/third_party/freetype/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/third_party/freetype/src/cff/cf2arrst.h b/third_party/freetype/src/cff/cf2arrst.h
index ff5ad8b..3c21a3b 100644
--- a/third_party/freetype/src/cff/cf2arrst.h
+++ b/third_party/freetype/src/cff/cf2arrst.h
@@ -36,8 +36,8 @@
 /***************************************************************************/
 
 
-#ifndef __CF2ARRST_H__
-#define __CF2ARRST_H__
+#ifndef CF2ARRST_H_
+#define CF2ARRST_H_
 
 
 #include "cf2error.h"
@@ -94,7 +94,7 @@
 FT_END_HEADER
 
 
-#endif /* __CF2ARRST_H__ */
+#endif /* CF2ARRST_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cf2blues.h b/third_party/freetype/src/cff/cf2blues.h
index 2f38fca..96fb60f 100644
--- a/third_party/freetype/src/cff/cf2blues.h
+++ b/third_party/freetype/src/cff/cf2blues.h
@@ -65,8 +65,8 @@
    */
 
 
-#ifndef __CF2BLUES_H__
-#define __CF2BLUES_H__
+#ifndef CF2BLUES_H_
+#define CF2BLUES_H_
 
 
 #include "cf2glue.h"
@@ -179,7 +179,7 @@
 FT_END_HEADER
 
 
-#endif /* __CF2BLUES_H__ */
+#endif /* CF2BLUES_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cf2error.c b/third_party/freetype/src/cff/cf2error.c
index b5595a3..e3dd69f 100644
--- a/third_party/freetype/src/cff/cf2error.c
+++ b/third_party/freetype/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/third_party/freetype/src/cff/cf2error.h b/third_party/freetype/src/cff/cf2error.h
index 6453ebc..512edd1 100644
--- a/third_party/freetype/src/cff/cf2error.h
+++ b/third_party/freetype/src/cff/cf2error.h
@@ -36,13 +36,13 @@
 /***************************************************************************/
 
 
-#ifndef __CF2ERROR_H__
-#define __CF2ERROR_H__
+#ifndef CF2ERROR_H_
+#define CF2ERROR_H_
 
 
 #include FT_MODULE_ERRORS_H
 
-#undef __FTERRORS_H__
+#undef FTERRORS_H_
 
 #undef  FT_ERR_PREFIX
 #define FT_ERR_PREFIX  CF2_Err_
@@ -70,7 +70,7 @@
    * 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
-   * error to propogate and be handled at the appropriate location in
+   * error to propagate and be handled at the appropriate location in
    * the code.
    *
    * This allows a style of code where the error code is initialized
@@ -113,7 +113,7 @@
 FT_END_HEADER
 
 
-#endif /* __CF2ERROR_H__ */
+#endif /* CF2ERROR_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cf2fixed.h b/third_party/freetype/src/cff/cf2fixed.h
index d6d9faf..2e4b503 100644
--- a/third_party/freetype/src/cff/cf2fixed.h
+++ b/third_party/freetype/src/cff/cf2fixed.h
@@ -36,8 +36,8 @@
 /***************************************************************************/
 
 
-#ifndef __CF2FIXED_H__
-#define __CF2FIXED_H__
+#ifndef CF2FIXED_H_
+#define CF2FIXED_H_
 
 
 FT_BEGIN_HEADER
@@ -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 */
@@ -89,7 +89,7 @@
 FT_END_HEADER
 
 
-#endif /*  __CF2FIXED_H__ */
+#endif /* CF2FIXED_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cf2font.c b/third_party/freetype/src/cff/cf2font.c
index 83fd348..a86e361 100644
--- a/third_party/freetype/src/cff/cf2font.c
+++ b/third_party/freetype/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/third_party/freetype/src/cff/cf2font.h b/third_party/freetype/src/cff/cf2font.h
index 86cf02f..17ecd17 100644
--- a/third_party/freetype/src/cff/cf2font.h
+++ b/third_party/freetype/src/cff/cf2font.h
@@ -36,12 +36,13 @@
 /***************************************************************************/
 
 
-#ifndef __CF2FONT_H__
-#define __CF2FONT_H__
+#ifndef CF2FONT_H_
+#define CF2FONT_H_
 
 
 #include "cf2ft.h"
 #include "cf2blues.h"
+#include "cffload.h"
 
 
 FT_BEGIN_HEADER
@@ -54,6 +55,7 @@
                                    /* (Hiragino Kaku Gothic ProN W3;      */
                                    /* 8.2d6e1; 2014-12-19) that exceed    */
                                    /* this limit                          */
+#define CF2_STORAGE_SIZE        32
 
 
   /* typedef is in `cf2glue.h' */
@@ -62,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:  */
@@ -73,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 */
@@ -115,7 +124,7 @@
 FT_END_HEADER
 
 
-#endif /* __CF2FONT_H__ */
+#endif /* CF2FONT_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cf2ft.c b/third_party/freetype/src/cff/cf2ft.c
index d2544a2..c0d067e 100644
--- a/third_party/freetype/src/cff/cf2ft.c
+++ b/third_party/freetype/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 )
@@ -544,14 +586,17 @@
   /* return 0 on success                                   */
   FT_LOCAL_DEF( CF2_Int )
   cf2_initGlobalRegionBuffer( CFF_Decoder*  decoder,
-                              CF2_UInt      idx,
+                              CF2_Int       subrNum,
                               CF2_Buffer    buf )
   {
+    CF2_UInt  idx;
+
+
     FT_ASSERT( decoder );
 
     FT_ZERO( buf );
 
-    idx += (CF2_UInt)decoder->globals_bias;
+    idx = (CF2_UInt)( subrNum + decoder->globals_bias );
     if ( idx >= decoder->num_globals )
       return TRUE;     /* error */
 
@@ -628,14 +673,17 @@
 
   FT_LOCAL_DEF( CF2_Int )
   cf2_initLocalRegionBuffer( CFF_Decoder*  decoder,
-                             CF2_UInt      idx,
+                             CF2_Int       subrNum,
                              CF2_Buffer    buf )
   {
+    CF2_UInt  idx;
+
+
     FT_ASSERT( decoder );
 
     FT_ZERO( buf );
 
-    idx += (CF2_UInt)decoder->locals_bias;
+    idx = (CF2_UInt)( subrNum + decoder->locals_bias );
     if ( idx >= decoder->num_locals )
       return TRUE;     /* error */
 
diff --git a/third_party/freetype/src/cff/cf2ft.h b/third_party/freetype/src/cff/cf2ft.h
index 3073df3..b054a6e 100644
--- a/third_party/freetype/src/cff/cf2ft.h
+++ b/third_party/freetype/src/cff/cf2ft.h
@@ -36,8 +36,8 @@
 /***************************************************************************/
 
 
-#ifndef __CF2FT_H__
-#define __CF2FT_H__
+#ifndef CF2FT_H_
+#define CF2FT_H_
 
 
 #include "cf2types.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 );
@@ -99,7 +111,7 @@
 
   FT_LOCAL( CF2_Int )
   cf2_initGlobalRegionBuffer( CFF_Decoder*  decoder,
-                              CF2_UInt      idx,
+                              CF2_Int       subrNum,
                               CF2_Buffer    buf );
   FT_LOCAL( FT_Error )
   cf2_getSeacComponent( CFF_Decoder*  decoder,
@@ -110,7 +122,7 @@
                          CF2_Buffer    buf );
   FT_LOCAL( CF2_Int )
   cf2_initLocalRegionBuffer( CFF_Decoder*  decoder,
-                             CF2_UInt      idx,
+                             CF2_Int       subrNum,
                              CF2_Buffer    buf );
 
   FT_LOCAL( CF2_Fixed )
@@ -141,7 +153,7 @@
 FT_END_HEADER
 
 
-#endif /* __CF2FT_H__ */
+#endif /* CF2FT_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cf2glue.h b/third_party/freetype/src/cff/cf2glue.h
index a24da39..56a7c24 100644
--- a/third_party/freetype/src/cff/cf2glue.h
+++ b/third_party/freetype/src/cff/cf2glue.h
@@ -36,8 +36,8 @@
 /***************************************************************************/
 
 
-#ifndef __CF2GLUE_H__
-#define __CF2GLUE_H__
+#ifndef CF2GLUE_H_
+#define CF2GLUE_H_
 
 
 /* common includes for other modules */
@@ -138,7 +138,7 @@
 FT_END_HEADER
 
 
-#endif /* __CF2GLUE_H__ */
+#endif /* CF2GLUE_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cf2hints.c b/third_party/freetype/src/cff/cf2hints.c
index 0e27000..c8f7dfe 100644
--- a/third_party/freetype/src/cff/cf2hints.c
+++ b/third_party/freetype/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;
 
@@ -587,8 +587,9 @@
     }
 
     /* paired edges must be in proper order */
-    FT_ASSERT( !isPair                                         ||
-               topHintEdge->csCoord >= bottomHintEdge->csCoord );
+    if ( isPair                                         &&
+         topHintEdge->csCoord < bottomHintEdge->csCoord )
+      return;
 
     /* linear search to find index value of insertion point */
     indexInsert = 0;
diff --git a/third_party/freetype/src/cff/cf2hints.h b/third_party/freetype/src/cff/cf2hints.h
index f25d91b..a898454 100644
--- a/third_party/freetype/src/cff/cf2hints.h
+++ b/third_party/freetype/src/cff/cf2hints.h
@@ -36,8 +36,8 @@
 /***************************************************************************/
 
 
-#ifndef __CF2HINTS_H__
-#define __CF2HINTS_H__
+#ifndef CF2HINTS_H_
+#define CF2HINTS_H_
 
 
 FT_BEGIN_HEADER
@@ -220,7 +220,7 @@
 
     /* character space miter limit threshold */
     CF2_Fixed  miterLimit;
-    /* vertical/horzizontal snap distance in character space */
+    /* vertical/horizontal snap distance in character space */
     CF2_Fixed  snapThreshold;
 
     FT_Vector  offsetStart0;  /* first and second points of first */
@@ -283,7 +283,7 @@
 FT_END_HEADER
 
 
-#endif /* __CF2HINTS_H__ */
+#endif /* CF2HINTS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cf2intrp.c b/third_party/freetype/src/cff/cf2intrp.c
index ff3fa9a..6bf298a 100644
--- a/third_party/freetype/src/cff/cf2intrp.c
+++ b/third_party/freetype/src/cff/cf2intrp.c
@@ -47,6 +47,8 @@
 
 #include "cf2error.h"
 
+#include "cffload.h"
+
 
   /*************************************************************************/
   /*                                                                       */
@@ -184,7 +186,7 @@
       return;
 
     FT_ASSERT( hintmask->byteCount > 0 );
-    FT_ASSERT( hintmask->byteCount <
+    FT_ASSERT( hintmask->byteCount <=
                  sizeof ( hintmask->mask ) / sizeof ( hintmask->mask[0] ) );
 
     /* set mask to all ones */
@@ -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     */
   };
 
 
@@ -293,7 +296,8 @@
     /* variable accumulates delta values from operand stack */
     CF2_Fixed  position = hintOffset;
 
-    if ( hasWidthArg && ! *haveWidth )
+
+    if ( hasWidthArg && !*haveWidth )
       *width = cf2_stack_getReal( opStack, 0 ) +
                  cf2_getNominalWidthX( font->decoder );
 
@@ -343,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++ )
@@ -402,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
@@ -444,8 +485,11 @@
     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' */
+
     /* instruction limit; 20,000,000 matches Avalon */
     FT_UInt32  instructionLimit = 20000000UL;
 
@@ -466,6 +510,8 @@
     CF2_GlyphPathRec  glyphPath;
 
 
+    FT_ZERO( &storage );
+
     /* initialize the remaining objects */
     cf2_arrstack_init( &subrStack,
                        memory,
@@ -515,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 );
@@ -556,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;
@@ -581,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" ));
@@ -608,7 +733,7 @@
                      0 );
 
         if ( font->decoder->width_only )
-            goto exit;
+          goto exit;
 
         break;
 
@@ -632,7 +757,7 @@
                      0 );
 
         if ( font->decoder->width_only )
-            goto exit;
+          goto exit;
 
         break;
 
@@ -646,7 +771,7 @@
         haveWidth = TRUE;
 
         if ( font->decoder->width_only )
-            goto exit;
+          goto exit;
 
         curY += cf2_stack_popFixed( opStack );
 
@@ -680,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" ));
@@ -746,7 +871,7 @@
       case cf2_cmdCALLGSUBR:
       case cf2_cmdCALLSUBR:
         {
-          CF2_UInt  subrIndex;
+          CF2_Int  subrNum;
 
 
           FT_TRACE4(( op1 == cf2_cmdCALLGSUBR ? " callgsubr"
@@ -766,17 +891,17 @@
                            (size_t)charstringIndex + 1 );
 
           /* set up the new CFF region and pointer */
-          subrIndex = (CF2_UInt)cf2_stack_popInt( opStack );
+          subrNum = cf2_stack_popInt( opStack );
 
           switch ( op1 )
           {
           case cf2_cmdCALLGSUBR:
             FT_TRACE4(( " (idx %d, entering level %d)\n",
-                        subrIndex + (CF2_UInt)decoder->globals_bias,
+                        subrNum + decoder->globals_bias,
                         charstringIndex + 1 ));
 
             if ( cf2_initGlobalRegionBuffer( decoder,
-                                             subrIndex,
+                                             subrNum,
                                              charstring ) )
             {
               lastError = FT_THROW( Invalid_Glyph_Format );
@@ -787,11 +912,11 @@
           default:
             /* cf2_cmdCALLSUBR */
             FT_TRACE4(( " (idx %d, entering level %d)\n",
-                        subrIndex + (CF2_UInt)decoder->locals_bias,
+                        subrNum + decoder->locals_bias,
                         charstringIndex + 1 ));
 
             if ( cf2_initLocalRegionBuffer( decoder,
-                                            subrIndex,
+                                            subrNum,
                                             charstring ) )
             {
               lastError = FT_THROW( Invalid_Glyph_Format );
@@ -825,135 +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;
-
-          /* TODO: should these operators be supported? */
-          case cf2_escAND: /* in spec */
-            FT_TRACE4(( " and\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escOR: /* in spec */
-            FT_TRACE4(( " or\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escNOT: /* in spec */
-            FT_TRACE4(( " not\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escABS: /* in spec */
-            FT_TRACE4(( " abs\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escADD: /* in spec */
-            FT_TRACE4(( " add\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escSUB: /* in spec */
-            FT_TRACE4(( " sub\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escDIV: /* in spec */
-            FT_TRACE4(( " div\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escNEG: /* in spec */
-            FT_TRACE4(( " neg\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escEQ: /* in spec */
-            FT_TRACE4(( " eq\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escDROP: /* in spec */
-            FT_TRACE4(( " drop\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escPUT: /* in spec */
-            FT_TRACE4(( " put\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escGET: /* in spec */
-            FT_TRACE4(( " get\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escIFELSE: /* in spec */
-            FT_TRACE4(( " ifelse\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escRANDOM: /* in spec */
-            FT_TRACE4(( " random\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escMUL: /* in spec */
-            FT_TRACE4(( " mul\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escSQRT: /* in spec */
-            FT_TRACE4(( " sqrt\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escDUP: /* in spec */
-            FT_TRACE4(( " dup\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escEXCH: /* in spec */
-            FT_TRACE4(( " exch\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escINDEX: /* in spec */
-            FT_TRACE4(( " index\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escROLL: /* in spec */
-            FT_TRACE4(( " roll\n" ));
-
-            CF2_FIXME;
-            break;
-
           case cf2_escHFLEX:
             {
               static const FT_Bool  readFromStack[12] =
@@ -1050,6 +1050,7 @@
             }
             continue;
 
+          /* these opcodes are reserved in both CFF & CFF2 */
           case cf2_escRESERVED_1:
           case cf2_escRESERVED_2:
           case cf2_escRESERVED_6:
@@ -1063,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:
@@ -1085,12 +1416,13 @@
         haveWidth = TRUE;
 
         if ( font->decoder->width_only )
-            goto exit;
+          goto exit;
 
         /* 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 */
@@ -1117,8 +1449,8 @@
           error2 = cf2_getSeacComponent( decoder, achar, &component );
           if ( error2 )
           {
-             lastError = error2;      /* pass FreeType error through */
-             goto exit;
+            lastError = error2;      /* pass FreeType error through */
+            goto exit;
           }
           cf2_interpT2CharString( font,
                                   &component,
@@ -1172,7 +1504,7 @@
                      0 );
 
         if ( font->decoder->width_only )
-            goto exit;
+          goto exit;
 
         if ( op1 == cf2_cmdHINTMASK )
         {
@@ -1231,7 +1563,7 @@
         haveWidth = TRUE;
 
         if ( font->decoder->width_only )
-            goto exit;
+          goto exit;
 
         curY += cf2_stack_popFixed( opStack );
         curX += cf2_stack_popFixed( opStack );
@@ -1250,7 +1582,7 @@
         haveWidth = TRUE;
 
         if ( font->decoder->width_only )
-            goto exit;
+          goto exit;
 
         curX += cf2_stack_popFixed( opStack );
 
@@ -1319,7 +1651,7 @@
             {
               x1 = cf2_stack_getReal( opStack, index ) + curX;
 
-              ++index;
+              index++;
             }
             else
               x1 = curX;
@@ -1364,7 +1696,7 @@
             {
               y1 = cf2_stack_getReal( opStack, index ) + curY;
 
-              ++index;
+              index++;
             }
             else
               y1 = curY;
@@ -1392,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, */
@@ -1421,7 +1753,7 @@
               {
                 x3 = cf2_stack_getReal( opStack, index + 4 ) + x2;
 
-                ++index;
+                index++;
               }
               else
                 x3 = x2;
@@ -1440,7 +1772,7 @@
               {
                 y3 = cf2_stack_getReal( opStack, index + 4 ) + y2;
 
-                ++index;
+                index++;
               }
               else
                 y3 = y2;
@@ -1463,9 +1795,12 @@
         {
           CF2_Int  v;
 
+          CF2_Int  byte1 = cf2_buf_readByte( charstring );
+          CF2_Int  byte2 = cf2_buf_readByte( charstring );
 
-          v = (FT_Short)( ( cf2_buf_readByte( charstring ) << 8 ) |
-                            cf2_buf_readByte( charstring )        );
+
+          v = (FT_Short)( ( byte1 << 8 ) |
+                            byte2        );
 
           FT_TRACE4(( " %d", v ));
 
@@ -1527,14 +1862,18 @@
           {
             CF2_Fixed  v;
 
+            FT_UInt32  byte1 = (FT_UInt32)cf2_buf_readByte( charstring );
+            FT_UInt32  byte2 = (FT_UInt32)cf2_buf_readByte( charstring );
+            FT_UInt32  byte3 = (FT_UInt32)cf2_buf_readByte( charstring );
+            FT_UInt32  byte4 = (FT_UInt32)cf2_buf_readByte( charstring );
 
-            v = (CF2_Fixed)
-                  ( ( (FT_UInt32)cf2_buf_readByte( charstring ) << 24 ) |
-                    ( (FT_UInt32)cf2_buf_readByte( charstring ) << 16 ) |
-                    ( (FT_UInt32)cf2_buf_readByte( charstring ) <<  8 ) |
-                      (FT_UInt32)cf2_buf_readByte( charstring )         );
 
-            FT_TRACE4(( " %.2f", v / 65536.0 ));
+            v = (CF2_Fixed)( ( byte1 << 24 ) |
+                             ( byte2 << 16 ) |
+                             ( byte3 <<  8 ) |
+                               byte4         );
+
+            FT_TRACE4(( " %.5f", v / 65536.0 ));
 
             cf2_stack_pushFixed( opStack, v );
           }
@@ -1555,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/third_party/freetype/src/cff/cf2intrp.h b/third_party/freetype/src/cff/cf2intrp.h
index b5d8947..ec030e8 100644
--- a/third_party/freetype/src/cff/cf2intrp.h
+++ b/third_party/freetype/src/cff/cf2intrp.h
@@ -36,8 +36,8 @@
 /***************************************************************************/
 
 
-#ifndef __CF2INTRP_H__
-#define __CF2INTRP_H__
+#ifndef CF2INTRP_H_
+#define CF2INTRP_H_
 
 
 #include "cf2ft.h"
@@ -77,7 +77,7 @@
 FT_END_HEADER
 
 
-#endif /* __CF2INTRP_H__ */
+#endif /* CF2INTRP_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cf2read.h b/third_party/freetype/src/cff/cf2read.h
index 7ef7c8c..b0b0db8 100644
--- a/third_party/freetype/src/cff/cf2read.h
+++ b/third_party/freetype/src/cff/cf2read.h
@@ -36,8 +36,8 @@
 /***************************************************************************/
 
 
-#ifndef __CF2READ_H__
-#define __CF2READ_H__
+#ifndef CF2READ_H_
+#define CF2READ_H_
 
 
 FT_BEGIN_HEADER
@@ -62,7 +62,7 @@
 FT_END_HEADER
 
 
-#endif /* __CF2READ_H__ */
+#endif /* CF2READ_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cf2stack.c b/third_party/freetype/src/cff/cf2stack.c
index 8332b5d..12a026d 100644
--- a/third_party/freetype/src/cff/cf2stack.c
+++ b/third_party/freetype/src/cff/cf2stack.c
@@ -51,21 +51,31 @@
   /* `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_QNEW */
+    FT_Error  error = FT_Err_Ok;     /* for FT_NEW */
 
     CF2_Stack  stack = NULL;
 
 
-    if ( !FT_QNEW( stack ) )
+    if ( !FT_NEW( stack ) )
     {
-      /* initialize the structure; FT_QNEW zeroes it */
+      /* 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,24 +150,24 @@
       return 0;   /* type mismatch */
     }
 
-    --stack->top;
+    stack->top--;
 
     return stack->top->u.i;
   }
 
 
   /* Note: type mismatch is silently cast */
-  /* TODO: check this */
+  /* TODO: check this                     */
   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 )
     {
@@ -170,12 +182,12 @@
 
 
   /* Note: type mismatch is silently cast */
-  /* TODO: check this */
+  /* TODO: check this                     */
   FT_LOCAL_DEF( CF2_Fixed )
   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,10 +207,121 @@
   }
 
 
+  /* 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 )
+  {
+    /* we initialize this variable to avoid compiler warnings */
+    CF2_StackNumber  last = { { 0 }, CF2_NumberInt };
+
+    CF2_Int  start_idx, idx, i;
+
+
+    if ( count < 2 )
+      return; /* nothing to do (values 0 and 1), or undefined value */
+
+    if ( (CF2_UInt)count > cf2_stack_count( stack ) )
+    {
+      CF2_SET_ERROR( stack->error, Stack_Overflow );
+      return;
+    }
+
+    if ( shift < 0 )
+      shift = -( ( -shift ) % count );
+    else
+      shift %= count;
+
+    if ( shift == 0 )
+      return; /* nothing to do */
+
+    /* We use the following algorithm to do the rolling, */
+    /* which needs two temporary variables only.         */
+    /*                                                   */
+    /* Example:                                          */
+    /*                                                   */
+    /*   count = 8                                       */
+    /*   shift = 2                                       */
+    /*                                                   */
+    /*   stack indices before roll:  7 6 5 4 3 2 1 0     */
+    /*   stack indices after roll:   1 0 7 6 5 4 3 2     */
+    /*                                                   */
+    /* The value of index 0 gets moved to index 2, while */
+    /* the old value of index 2 gets moved to index 4,   */
+    /* and so on.  We thus have the following copying    */
+    /* chains for shift value 2.                         */
+    /*                                                   */
+    /*   0 -> 2 -> 4 -> 6 -> 0                           */
+    /*   1 -> 3 -> 5 -> 7 -> 1                           */
+    /*                                                   */
+    /* If `count' and `shift' are incommensurable, we    */
+    /* have a single chain only.  Otherwise, increase    */
+    /* the start index by 1 after the first chain, then  */
+    /* do the next chain until all elements in all       */
+    /* chains are handled.                               */
+
+    start_idx = -1;
+    idx       = -1;
+    for ( i = 0; i < count; i++ )
+    {
+      CF2_StackNumber  tmp;
+
+
+      if ( start_idx == idx )
+      {
+        start_idx++;
+        idx  = start_idx;
+        last = stack->buffer[idx];
+      }
+
+      idx += shift;
+      if ( idx >= count )
+        idx -= count;
+      else if ( idx < 0 )
+        idx += count;
+
+      tmp                = stack->buffer[idx];
+      stack->buffer[idx] = last;
+      last               = tmp;
+    }
+  }
+
+
   FT_LOCAL_DEF( void )
   cf2_stack_clear( CF2_Stack  stack )
   {
-    stack->top = &stack->buffer[0];
+    stack->top = stack->buffer;
   }
 
 
diff --git a/third_party/freetype/src/cff/cf2stack.h b/third_party/freetype/src/cff/cf2stack.h
index 7d6d196..ef08eef 100644
--- a/third_party/freetype/src/cff/cf2stack.h
+++ b/third_party/freetype/src/cff/cf2stack.h
@@ -36,8 +36,8 @@
 /***************************************************************************/
 
 
-#ifndef __CF2STACK_H__
-#define __CF2STACK_H__
+#ifndef CF2STACK_H_
+#define CF2STACK_H_
 
 
 FT_BEGIN_HEADER
@@ -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,19 @@
   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,
+                  CF2_Int    count,
+                  CF2_Int    idx );
 
   FT_LOCAL( void )
   cf2_stack_clear( CF2_Stack  stack );
@@ -100,7 +115,7 @@
 FT_END_HEADER
 
 
-#endif /* __CF2STACK_H__ */
+#endif /* CF2STACK_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cf2types.h b/third_party/freetype/src/cff/cf2types.h
index ac6a022..5b7e123 100644
--- a/third_party/freetype/src/cff/cf2types.h
+++ b/third_party/freetype/src/cff/cf2types.h
@@ -36,8 +36,8 @@
 /***************************************************************************/
 
 
-#ifndef __CF2TYPES_H__
-#define __CF2TYPES_H__
+#ifndef CF2TYPES_H_
+#define CF2TYPES_H_
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
@@ -72,7 +72,7 @@
 FT_END_HEADER
 
 
-#endif /* __CF2TYPES_H__ */
+#endif /* CF2TYPES_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cff.c b/third_party/freetype/src/cff/cff.c
index bb2cfb5..545fb20 100644
--- a/third_party/freetype/src/cff/cff.c
+++ b/third_party/freetype/src/cff/cff.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType OpenType driver component (body only).                      */
 /*                                                                         */
-/*  Copyright 1996-2015 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/third_party/freetype/src/cff/cffcmap.c b/third_party/freetype/src/cff/cffcmap.c
index e7538e9..4adce7a 100644
--- a/third_party/freetype/src/cff/cffcmap.c
+++ b/third_party/freetype/src/cff/cffcmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF character mapping table (cmap) support (body).                   */
 /*                                                                         */
-/*  Copyright 2002-2015 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/third_party/freetype/src/cff/cffcmap.h b/third_party/freetype/src/cff/cffcmap.h
index 6eaed63..7792e04 100644
--- a/third_party/freetype/src/cff/cffcmap.h
+++ b/third_party/freetype/src/cff/cffcmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF character mapping table (cmap) support (specification).          */
 /*                                                                         */
-/*  Copyright 2002-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __CFFCMAP_H__
-#define __CFFCMAP_H__
+#ifndef CFFCMAP_H_
+#define CFFCMAP_H_
 
 #include "cffobjs.h"
 
@@ -61,7 +61,7 @@
 
 FT_END_HEADER
 
-#endif /* __CFFCMAP_H__ */
+#endif /* CFFCMAP_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cffdrivr.c b/third_party/freetype/src/cff/cffdrivr.c
index a718b7a..467b3ed 100644
--- a/third_party/freetype/src/cff/cffdrivr.c
+++ b/third_party/freetype/src/cff/cffdrivr.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType font driver implementation (body).                          */
 /*                                                                         */
-/*  Copyright 1996-2015 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,10 @@
 #include "cffcmap.h"
 #include "cffparse.h"
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+#include FT_SERVICE_MULTIPLE_MASTERS_H
+#endif
+
 #include "cfferrs.h"
 #include "cffpic.h"
 
@@ -207,6 +211,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 +243,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 +309,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 +379,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,8 +430,9 @@
 
   FT_DEFINE_SERVICE_GLYPHDICTREC(
     cff_service_glyph_dict,
-    (FT_GlyphDict_GetNameFunc)  cff_get_glyph_name,
-    (FT_GlyphDict_NameIndexFunc)cff_get_name_index
+
+    (FT_GlyphDict_GetNameFunc)  cff_get_glyph_name,      /* get_name   */
+    (FT_GlyphDict_NameIndexFunc)cff_get_name_index       /* name_index */
   )
 
 
@@ -383,11 +456,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,11 +494,14 @@
 
   FT_DEFINE_SERVICE_PSINFOREC(
     cff_service_ps_info,
-    (PS_GetFontInfoFunc)   cff_ps_get_font_info,
-    (PS_GetFontExtraFunc)  NULL,
-    (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
-    (PS_GetFontPrivateFunc)NULL,        /* unsupported with CFF fonts */
-    (PS_GetFontValueFunc)  NULL         /* not implemented            */
+
+    (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  */
+    /* unsupported with CFF fonts */
+    (PS_GetFontPrivateFunc)NULL,                    /* ps_get_font_private */
+    /* not implemented            */
+    (PS_GetFontValueFunc)  NULL                     /* ps_get_font_value   */
   )
 
 
@@ -444,14 +520,15 @@
     /* following the OpenType specification 1.7, we return the name stored */
     /* in the `name' table for a CFF wrapped into an SFNT container        */
 
-    if ( sfnt )
+    if ( FT_IS_SFNT( FT_FACE( face ) ) && sfnt )
     {
       FT_Library             library     = FT_FACE_LIBRARY( face );
       FT_Module              sfnt_module = FT_Get_Module( library, "sfnt" );
       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 )
@@ -464,7 +541,8 @@
 
   FT_DEFINE_SERVICE_PSFONTNAMEREC(
     cff_service_ps_name,
-    (FT_PsName_GetFunc)cff_get_ps_name
+
+    (FT_PsName_GetFunc)cff_get_ps_name      /* get_ps_font_name */
   )
 
 
@@ -489,21 +567,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;
   }
@@ -511,7 +589,8 @@
 
   FT_DEFINE_SERVICE_TTCMAPSREC(
     cff_service_get_cmap_info,
-    (TT_CMap_Info_GetFunc)cff_get_cmap_info
+
+    (TT_CMap_Info_GetFunc)cff_get_cmap_info    /* get_cmap_info */
   )
 
 
@@ -542,7 +621,7 @@
 
       if ( registry )
       {
-        if ( cff->registry == NULL )
+        if ( !cff->registry )
           cff->registry = cff_index_get_sid_string( cff,
                                                     dict->cid_registry );
         *registry = cff->registry;
@@ -550,7 +629,7 @@
 
       if ( ordering )
       {
-        if ( cff->ordering == NULL )
+        if ( !cff->ordering )
           cff->ordering = cff_index_get_sid_string( cff,
                                                     dict->cid_ordering );
         *ordering = cff->ordering;
@@ -641,9 +720,13 @@
 
   FT_DEFINE_SERVICE_CIDREC(
     cff_service_cid_info,
-    (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros,
-    (FT_CID_GetIsInternallyCIDKeyedFunc)      cff_get_is_cid,
-    (FT_CID_GetCIDFromGlyphIndexFunc)         cff_get_cid_from_glyph_index
+
+    (FT_CID_GetRegistryOrderingSupplementFunc)
+      cff_get_ros,                             /* get_ros                  */
+    (FT_CID_GetIsInternallyCIDKeyedFunc)
+      cff_get_is_cid,                          /* get_is_cid               */
+    (FT_CID_GetCIDFromGlyphIndexFunc)
+      cff_get_cid_from_glyph_index             /* get_cid_from_glyph_index */
   )
 
 
@@ -654,26 +737,62 @@
   static FT_Error
   cff_property_set( FT_Module    module,         /* CFF_Driver */
                     const char*  property_name,
-                    const void*  value )
+                    const void*  value,
+                    FT_Bool      value_is_string )
   {
     FT_Error    error  = FT_Err_Ok;
     CFF_Driver  driver = (CFF_Driver)module;
 
+#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+    FT_UNUSED( value_is_string );
+#endif
+
 
     if ( !ft_strcmp( property_name, "darkening-parameters" ) )
     {
-      FT_Int*  darken_params = (FT_Int*)value;
+      FT_Int*  darken_params;
+      FT_Int   x1, y1, x2, y2, x3, y3, x4, y4;
 
-      FT_Int  x1 = darken_params[0];
-      FT_Int  y1 = darken_params[1];
-      FT_Int  x2 = darken_params[2];
-      FT_Int  y2 = darken_params[3];
-      FT_Int  x3 = darken_params[4];
-      FT_Int  y3 = darken_params[5];
-      FT_Int  x4 = darken_params[6];
-      FT_Int  y4 = darken_params[7];
+#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+      FT_Int   dp[8];
 
 
+      if ( value_is_string )
+      {
+        const char*  s = (const char*)value;
+        char*        ep;
+        int          i;
+
+
+        /* eight comma-separated numbers */
+        for ( i = 0; i < 7; i++ )
+        {
+          dp[i] = (FT_Int)ft_strtol( s, &ep, 10 );
+          if ( *ep != ',' || s == ep )
+            return FT_THROW( Invalid_Argument );
+
+          s = ep + 1;
+        }
+
+        dp[7] = (FT_Int)ft_strtol( s, &ep, 10 );
+        if ( !( *ep == '\0' || *ep == ' ' ) || s == ep )
+          return FT_THROW( Invalid_Argument );
+
+        darken_params = dp;
+      }
+      else
+#endif
+        darken_params = (FT_Int*)value;
+
+      x1 = darken_params[0];
+      y1 = darken_params[1];
+      x2 = darken_params[2];
+      y2 = darken_params[3];
+      x3 = darken_params[4];
+      y3 = darken_params[5];
+      x4 = darken_params[6];
+      y4 = darken_params[7];
+
       if ( x1 < 0   || x2 < 0   || x3 < 0   || x4 < 0   ||
            y1 < 0   || y2 < 0   || y3 < 0   || y4 < 0   ||
            x1 > x2  || x2 > x3  || x3 > x4              ||
@@ -693,24 +812,62 @@
     }
     else if ( !ft_strcmp( property_name, "hinting-engine" ) )
     {
-      FT_UInt*  hinting_engine = (FT_UInt*)value;
+#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+      if ( value_is_string )
+      {
+        const char*  s = (const char*)value;
 
 
-#ifndef CFF_CONFIG_OPTION_OLD_ENGINE
-      if ( *hinting_engine != FT_CFF_HINTING_ADOBE )
-        error = FT_ERR( Unimplemented_Feature );
+        if ( !ft_strcmp( s, "adobe" ) )
+          driver->hinting_engine = FT_CFF_HINTING_ADOBE;
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+        else if ( !ft_strcmp( s, "freetype" ) )
+          driver->hinting_engine = FT_CFF_HINTING_FREETYPE;
+#endif
+        else
+          return FT_THROW( Invalid_Argument );
+      }
       else
 #endif
-        driver->hinting_engine = *hinting_engine;
+      {
+        FT_UInt*  hinting_engine = (FT_UInt*)value;
 
-      return error;
+        if ( *hinting_engine == FT_CFF_HINTING_ADOBE
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+             || *hinting_engine == FT_CFF_HINTING_FREETYPE
+#endif
+           )
+          driver->hinting_engine = *hinting_engine;
+        else
+          error = FT_ERR( Unimplemented_Feature );
+
+        return error;
+      }
     }
     else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
     {
-      FT_Bool*  no_stem_darkening = (FT_Bool*)value;
+#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+      if ( value_is_string )
+      {
+        const char*  s   = (const char*)value;
+        long         nsd = ft_strtol( s, NULL, 10 );
 
 
-      driver->no_stem_darkening = *no_stem_darkening;
+        if ( nsd == 0 )
+          driver->no_stem_darkening = 0;
+        else if ( nsd == 1 )
+          driver->no_stem_darkening = 1;
+        else
+          return FT_THROW( Invalid_Argument );
+      }
+      else
+#endif
+      {
+        FT_Bool*  no_stem_darkening = (FT_Bool*)value;
+
+
+        driver->no_stem_darkening = *no_stem_darkening;
+      }
 
       return error;
     }
@@ -776,8 +933,92 @@
 
   FT_DEFINE_SERVICE_PROPERTIESREC(
     cff_service_properties,
-    (FT_Properties_SetFunc)cff_property_set,
-    (FT_Properties_GetFunc)cff_property_get )
+
+    (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     */
+  )
+#endif
 
 
   /*************************************************************************/
@@ -792,9 +1033,24 @@
   /*************************************************************************/
   /*************************************************************************/
 
-#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
+#if !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES && \
+     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_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,
@@ -803,9 +1059,22 @@
     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_SERVICEDESCREC7(
+    cff_services,
+
+    FT_SERVICE_ID_FONT_FORMAT,          FT_FONT_FORMAT_CFF,
+    FT_SERVICE_ID_MULTI_MASTERS,        &CFF_SERVICE_MULTI_MASTERS_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,
@@ -835,7 +1104,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 */
@@ -865,42 +1134,41 @@
   FT_DEFINE_DRIVER(
     cff_driver_class,
 
-      FT_MODULE_FONT_DRIVER       |
-      FT_MODULE_DRIVER_SCALABLE   |
-      FT_MODULE_DRIVER_HAS_HINTER,
+      FT_MODULE_FONT_DRIVER          |
+      FT_MODULE_DRIVER_SCALABLE      |
+      FT_MODULE_DRIVER_HAS_HINTER    |
+      FT_MODULE_DRIVER_HINTS_LIGHTLY,
 
       sizeof ( CFF_DriverRec ),
       "cff",
       0x10000L,
       0x20000L,
 
-      0,   /* module-specific interface */
+      NULL,   /* module-specific interface */
 
-      cff_driver_init,
-      cff_driver_done,
-      cff_get_interface,
+      cff_driver_init,          /* FT_Module_Constructor  module_init   */
+      cff_driver_done,          /* FT_Module_Destructor   module_done   */
+      cff_get_interface,        /* FT_Module_Requester    get_interface */
 
-    /* now the specific driver fields */
     sizeof ( TT_FaceRec ),
     sizeof ( CFF_SizeRec ),
     sizeof ( CFF_GlyphSlotRec ),
 
-    cff_face_init,
-    cff_face_done,
-    cff_size_init,
-    cff_size_done,
-    cff_slot_init,
-    cff_slot_done,
+    cff_face_init,              /* FT_Face_InitFunc  init_face */
+    cff_face_done,              /* FT_Face_DoneFunc  done_face */
+    cff_size_init,              /* FT_Size_InitFunc  init_size */
+    cff_size_done,              /* FT_Size_DoneFunc  done_size */
+    cff_slot_init,              /* FT_Slot_InitFunc  init_slot */
+    cff_slot_done,              /* FT_Slot_DoneFunc  done_slot */
 
-    cff_glyph_load,
+    cff_glyph_load,             /* FT_Slot_LoadFunc  load_glyph */
 
-    cff_get_kerning,
-    0,                       /* FT_Face_AttachFunc */
-    cff_get_advances,
+    cff_get_kerning,            /* FT_Face_GetKerningFunc   get_kerning  */
+    NULL,                       /* FT_Face_AttachFunc       attach_file  */
+    cff_get_advances,           /* FT_Face_GetAdvancesFunc  get_advances */
 
-    cff_size_request,
-
-    CFF_SIZE_SELECT
+    cff_size_request,           /* FT_Size_RequestFunc  request_size */
+    CFF_SIZE_SELECT             /* FT_Size_SelectFunc   select_size  */
   )
 
 
diff --git a/third_party/freetype/src/cff/cffdrivr.h b/third_party/freetype/src/cff/cffdrivr.h
index 9527f5e..05381e6 100644
--- a/third_party/freetype/src/cff/cffdrivr.h
+++ b/third_party/freetype/src/cff/cffdrivr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level OpenType driver interface (specification).                */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __CFFDRIVER_H__
-#define __CFFDRIVER_H__
+#ifndef CFFDRIVER_H_
+#define CFFDRIVER_H_
 
 
 #include <ft2build.h>
@@ -32,7 +32,7 @@
 
 FT_END_HEADER
 
-#endif /* __CFFDRIVER_H__ */
+#endif /* CFFDRIVER_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cfferrs.h b/third_party/freetype/src/cff/cfferrs.h
index 543bdb0..40808c1 100644
--- a/third_party/freetype/src/cff/cfferrs.h
+++ b/third_party/freetype/src/cff/cfferrs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF error codes (specification only).                                */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -22,12 +22,12 @@
   /*                                                                       */
   /*************************************************************************/
 
-#ifndef __CFFERRS_H__
-#define __CFFERRS_H__
+#ifndef CFFERRS_H_
+#define CFFERRS_H_
 
 #include FT_MODULE_ERRORS_H
 
-#undef __FTERRORS_H__
+#undef FTERRORS_H_
 
 #undef  FT_ERR_PREFIX
 #define FT_ERR_PREFIX  CFF_Err_
@@ -36,7 +36,7 @@
 
 #include FT_ERRORS_H
 
-#endif /* __CFFERRS_H__ */
+#endif /* CFFERRS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cffgload.c b/third_party/freetype/src/cff/cffgload.c
index 5f57403..f8e80c1 100644
--- a/third_party/freetype/src/cff/cffgload.c
+++ b/third_party/freetype/src/cff/cffgload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType Glyph Loader (body).                                        */
 /*                                                                         */
-/*  Copyright 1996-2015 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 );
@@ -680,7 +680,7 @@
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
 
     {
-      CFF_Font  cff  = (CFF_Font)(face->extra.data);
+      CFF_Font  cff = (CFF_Font)(face->extra.data);
 
 
       return cff_index_access_element( &cff->charstrings_index, glyph_index,
@@ -826,7 +826,7 @@
       /* the seac operator must not be nested */
       decoder->seac = TRUE;
       error = cff_decoder_parse_charstrings( decoder, charstring,
-                                             charstring_len );
+                                             charstring_len, 0 );
       decoder->seac = FALSE;
 
       cff_free_glyph_data( face, &charstring, charstring_len );
@@ -856,7 +856,7 @@
       /* the seac operator must not be nested */
       decoder->seac = TRUE;
       error = cff_decoder_parse_charstrings( decoder, charstring,
-                                             charstring_len );
+                                             charstring_len, 0 );
       decoder->seac = FALSE;
 
       cff_free_glyph_data( face, &charstring, charstring_len );
@@ -895,13 +895,17 @@
   /*                                                                       */
   /*    charstring_len  :: The length in bytes of the charstring stream.   */
   /*                                                                       */
+  /*    in_dict         :: Set to 1 if function is called from top or      */
+  /*                       private DICT (needed for Multiple Master CFFs). */
+  /*                                                                       */
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
   FT_LOCAL_DEF( FT_Error )
   cff_decoder_parse_charstrings( CFF_Decoder*  decoder,
                                  FT_Byte*      charstring_base,
-                                 FT_ULong      charstring_len )
+                                 FT_ULong      charstring_len,
+                                 FT_Bool       in_dict )
   {
     FT_Error           error;
     CFF_Decoder_Zone*  zone;
@@ -913,6 +917,10 @@
     FT_Fixed*          stack;
     FT_Int             charstring_type =
                          decoder->cff->top_font.font_dict.charstring_type;
+    FT_UShort          num_designs =
+                         decoder->cff->top_font.font_dict.num_designs;
+    FT_UShort          num_axes =
+                         decoder->cff->top_font.font_dict.num_axes;
 
     T2_Hints_Funcs     hinter;
 
@@ -1018,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
 
       }
@@ -1241,6 +1249,44 @@
         if ( op == cff_op_unknown )
           continue;
 
+        /* in Multiple Master CFFs, T2 charstrings can appear in */
+        /* dictionaries, but some operators are prohibited       */
+        if ( in_dict )
+        {
+          switch ( op )
+          {
+          case cff_op_hstem:
+          case cff_op_vstem:
+          case cff_op_vmoveto:
+          case cff_op_rlineto:
+          case cff_op_hlineto:
+          case cff_op_vlineto:
+          case cff_op_rrcurveto:
+          case cff_op_hstemhm:
+          case cff_op_hintmask:
+          case cff_op_cntrmask:
+          case cff_op_rmoveto:
+          case cff_op_hmoveto:
+          case cff_op_vstemhm:
+          case cff_op_rcurveline:
+          case cff_op_rlinecurve:
+          case cff_op_vvcurveto:
+          case cff_op_hhcurveto:
+          case cff_op_vhcurveto:
+          case cff_op_hvcurveto:
+          case cff_op_hflex:
+          case cff_op_flex:
+          case cff_op_hflex1:
+          case cff_op_flex1:
+          case cff_op_callsubr:
+          case cff_op_callgsubr:
+            goto MM_Error;
+
+          default:
+            break;
+          }
+        }
+
         /* check arguments */
         req_args = cff_argument_counts[op];
         if ( req_args & CFF_COUNT_CHECK_WIDTH )
@@ -1278,7 +1324,9 @@
             case cff_op_endchar:
               /* If there is a width specified for endchar, we either have */
               /* 1 argument or 5 arguments.  We like to argue.             */
-              set_width_ok = ( num_args == 5 ) || ( num_args == 1 );
+              set_width_ok = in_dict
+                               ? 0
+                               : ( ( num_args == 5 ) || ( num_args == 1 ) );
               break;
 
             default:
@@ -1971,6 +2019,10 @@
             return error;
 
         case cff_op_endchar:
+          /* in dictionaries, `endchar' simply indicates end of data */
+          if ( in_dict )
+            return error;
+
           FT_TRACE4(( " endchar\n" ));
 
           /* We are going to emulate the seac operator. */
@@ -2082,15 +2134,14 @@
 
           if ( args[0] > 0 )
           {
-            FT_Int    count = 9;
-            FT_Fixed  root  = args[0];
+            FT_Fixed  root = args[0];
             FT_Fixed  new_root;
 
 
             for (;;)
             {
               new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
-              if ( new_root == root || count <= 0 )
+              if ( new_root == root )
                 break;
               root = new_root;
             }
@@ -2199,6 +2250,10 @@
 
             FT_TRACE4(( " put\n" ));
 
+            /* the Type2 specification before version 16-March-2000 */
+            /* didn't give a hard-coded size limit of the temporary */
+            /* storage array; instead, an argument of the           */
+            /* `MultipleMaster' operator set the size               */
             if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
               decoder->buildchar[idx] = val;
           }
@@ -2221,14 +2276,68 @@
           break;
 
         case cff_op_store:
-          FT_TRACE4(( " store\n"));
+          /* this operator was removed from the Type2 specification */
+          /* in version 16-March-2000                               */
 
-          goto Unimplemented;
+          /* since we currently don't handle interpolation of multiple */
+          /* master fonts, this is a no-op                             */
+          FT_TRACE4(( " store\n"));
+          break;
 
         case cff_op_load:
-          FT_TRACE4(( " load\n" ));
+          /* this operator was removed from the Type2 specification */
+          /* in version 16-March-2000                               */
+          {
+            FT_Int  reg_idx = (FT_Int)args[0];
+            FT_Int  idx     = (FT_Int)args[1];
+            FT_Int  count   = (FT_Int)args[2];
 
-          goto Unimplemented;
+
+            FT_TRACE4(( " load\n" ));
+
+            /* since we currently don't handle interpolation of multiple */
+            /* master fonts, we store a vector [1 0 0 ...] in the        */
+            /* temporary storage array regardless of the Registry index  */
+            if ( reg_idx >= 0 && reg_idx <= 2             &&
+                 idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS &&
+                 count >= 0 && count <= num_axes          )
+            {
+              FT_Int  end, i;
+
+
+              end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS );
+
+              if ( idx < end )
+                decoder->buildchar[idx] = 1 << 16;
+
+              for ( i = idx + 1; i < end; i++ )
+                decoder->buildchar[i] = 0;
+            }
+          }
+          break;
+
+        case cff_op_blend:
+          /* this operator was removed from the Type2 specification */
+          /* in version 16-March-2000                               */
+          {
+            FT_Int  num_results = (FT_Int)( args[0] >> 16 );
+
+
+            FT_TRACE4(( " blend\n" ));
+
+            if ( num_results < 0 )
+              goto Syntax_Error;
+
+            if ( num_results * (FT_Int)num_designs > num_args )
+              goto Stack_Underflow;
+
+            /* since we currently don't handle interpolation of multiple */
+            /* master fonts, return the `num_results' values of the      */
+            /* first master                                              */
+            args     -= num_results * ( num_designs - 1 );
+            num_args -= num_results * ( num_designs - 1 );
+          }
+          break;
 
         case cff_op_dotsection:
           /* this operator is deprecated and ignored by the parser */
@@ -2336,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" ));
@@ -2348,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" ));
@@ -2358,11 +2467,23 @@
           }
           break;
 
-        case cff_op_eq:
+        case cff_op_not:
           {
             FT_Fixed  cond = !args[0];
 
 
+            FT_TRACE4(( " not\n" ));
+
+            args[0] = cond ? 0x10000L : 0;
+            args++;
+          }
+          break;
+
+        case cff_op_eq:
+          {
+            FT_Fixed  cond = ( args[0] == args[1] );
+
+
             FT_TRACE4(( " eq\n" ));
 
             args[0] = cond ? 0x10000L : 0;
@@ -2489,7 +2610,6 @@
           break;
 
         default:
-        Unimplemented:
           FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
 
           if ( ip[-1] == 12 )
@@ -2513,6 +2633,11 @@
   Fail:
     return error;
 
+  MM_Error:
+    FT_TRACE4(( "cff_decoder_parse_charstrings:"
+                " invalid opcode found in top DICT charstring\n"));
+    return FT_THROW( Invalid_File_Format );
+
   Syntax_Error:
     FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
     return FT_THROW( Invalid_File_Format );
@@ -2586,7 +2711,8 @@
         if ( !error )
           error = cff_decoder_parse_charstrings( &decoder,
                                                  charstring,
-                                                 charstring_len );
+                                                 charstring_len,
+                                                 0 );
 
         cff_free_glyph_data( face, &charstring, &charstring_len );
       }
@@ -2816,6 +2942,7 @@
       cff_decoder_init( &decoder, face, size, glyph, hinting,
                         FT_LOAD_TARGET_MODE( load_flags ) );
 
+      /* this is for pure CFFs */
       if ( load_flags & FT_LOAD_ADVANCE_ONLY )
         decoder.width_only = TRUE;
 
@@ -2837,7 +2964,8 @@
       if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
         error = cff_decoder_parse_charstrings( &decoder,
                                                charstring,
-                                               charstring_len );
+                                               charstring_len,
+                                               0 );
       else
 #endif
       {
diff --git a/third_party/freetype/src/cff/cffgload.h b/third_party/freetype/src/cff/cffgload.h
index 5f2655f..0fa93b4 100644
--- a/third_party/freetype/src/cff/cffgload.h
+++ b/third_party/freetype/src/cff/cffgload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType Glyph Loader (specification).                               */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __CFFGLOAD_H__
-#define __CFFGLOAD_H__
+#ifndef CFFGLOAD_H_
+#define CFFGLOAD_H_
 
 
 #include <ft2build.h>
@@ -227,7 +227,8 @@
   FT_LOCAL( FT_Error )
   cff_decoder_parse_charstrings( CFF_Decoder*  decoder,
                                  FT_Byte*      charstring_base,
-                                 FT_ULong      charstring_len );
+                                 FT_ULong      charstring_len,
+                                 FT_Bool       in_dict );
 #endif
 
   FT_LOCAL( FT_Error )
@@ -239,7 +240,7 @@
 
 FT_END_HEADER
 
-#endif /* __CFFGLOAD_H__ */
+#endif /* CFFGLOAD_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cffload.c b/third_party/freetype/src/cff/cffload.c
index c61222d..935e612 100644
--- a/third_party/freetype/src/cff/cffload.c
+++ b/third_party/freetype/src/cff/cffload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType and CFF data/program tables loader (body).                  */
 /*                                                                         */
-/*  Copyright 1996-2015 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;
 
@@ -382,28 +404,31 @@
   static FT_Error
   cff_index_get_pointers( CFF_Index   idx,
                           FT_Byte***  table,
-                          FT_Byte**   pool )
+                          FT_Byte**   pool,
+                          FT_ULong*   pool_size )
   {
     FT_Error   error     = FT_Err_Ok;
     FT_Memory  memory    = idx->stream->memory;
 
     FT_Byte**  t         = NULL;
     FT_Byte*   new_bytes = NULL;
+    FT_ULong   new_size;
 
 
     *table = NULL;
 
-    if ( idx->offsets == NULL )
+    if ( !idx->offsets )
     {
       error = cff_index_load_offsets( idx );
       if ( error )
         goto Exit;
     }
 
-    if ( idx->count > 0                                        &&
-         !FT_NEW_ARRAY( t, idx->count + 1 )                    &&
-         ( !pool || !FT_ALLOC( new_bytes,
-                               idx->data_size + idx->count ) ) )
+    new_size = idx->data_size + idx->count;
+
+    if ( idx->count > 0                                &&
+         !FT_NEW_ARRAY( t, idx->count + 1 )            &&
+         ( !pool || !FT_ALLOC( new_bytes, new_size ) ) )
     {
       FT_ULong  n, cur_offset;
       FT_ULong  extra = 0;
@@ -459,6 +484,8 @@
 
       if ( pool )
         *pool = new_bytes;
+      if ( pool_size )
+        *pool_size = new_size;
     }
 
   Exit:
@@ -488,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 );
@@ -501,8 +528,8 @@
           {
             element++;
             off2 = cff_index_read_offset( idx, &error );
-          }
-          while ( off2 == 0 && element < idx->count );
+
+          } while ( off2 == 0 && element < idx->count );
         }
       }
       else   /* use offsets table */
@@ -584,20 +611,26 @@
                       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;
 
     if ( !FT_ALLOC( name, byte_len + 1 ) )
     {
-      FT_MEM_COPY( name, bytes, byte_len );
+      if ( byte_len )
+        FT_MEM_COPY( name, bytes, byte_len );
       name[byte_len] = 0;
     }
     cff_index_forget_element( idx, &bytes );
@@ -719,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:
@@ -771,6 +809,7 @@
       ;
     }
 
+  Exit:
     return fd;
   }
 
@@ -809,7 +848,7 @@
     /* When multiple GIDs map to the same CID, we choose the lowest */
     /* GID.  This is not described in any spec, but it matches the  */
     /* behaviour of recent Acroread versions.                       */
-    for ( j = (FT_Long)num_glyphs - 1; j >= 0 ; j-- )
+    for ( j = (FT_Long)num_glyphs - 1; j >= 0; j-- )
       charset->cids[charset->sids[j]] = (FT_UShort)j;
 
     charset->max_cid    = max_cid;
@@ -871,8 +910,8 @@
     FT_UShort  glyph_sid;
 
 
-    /* If the the offset is greater than 2, we have to parse the */
-    /* charset table.                                            */
+    /* If the offset is greater than 2, we have to parse the charset */
+    /* table.                                                        */
     if ( offset > 2 )
     {
       FT_UInt  j;
@@ -1049,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;
@@ -1300,26 +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 );
+    /* 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;
@@ -1342,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;
@@ -1358,35 +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 );
-
-      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 )
@@ -1395,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 );
+      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;
   }
 
@@ -1418,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 );
     }
   }
 
@@ -1427,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
     };
 
@@ -1453,42 +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 ) ) )
-      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;
 
@@ -1534,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" ));
@@ -1582,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 );
@@ -1614,13 +2376,13 @@
     font->num_glyphs = font->charstrings_index.count;
 
     error = cff_index_get_pointers( &font->global_subrs_index,
-                                    &font->global_subrs, NULL );
+                                    &font->global_subrs, NULL, NULL );
 
     if ( error )
       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 );
 
@@ -1668,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++ )
@@ -1680,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/third_party/freetype/src/cff/cffload.h b/third_party/freetype/src/cff/cffload.h
index 459e7b0..8be6452 100644
--- a/third_party/freetype/src/cff/cffload.h
+++ b/third_party/freetype/src/cff/cffload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType & CFF data/program tables loader (specification).           */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,12 +16,14 @@
 /***************************************************************************/
 
 
-#ifndef __CFFLOAD_H__
-#define __CFFLOAD_H__
+#ifndef CFFLOAD_H_
+#define CFFLOAD_H_
 
 
 #include <ft2build.h>
 #include "cfftypes.h"
+#include "cffparse.h"
+#include "cffobjs.h"  /* for CFF_Face */
 
 
 FT_BEGIN_HEADER
@@ -60,24 +62,62 @@
 
 
   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
 
-#endif /* __CFFLOAD_H__ */
+#endif /* CFFLOAD_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cffobjs.c b/third_party/freetype/src/cff/cffobjs.c
index 0e0d5b0..a639350 100644
--- a/third_party/freetype/src/cff/cffobjs.c
+++ b/third_party/freetype/src/cff/cffobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType objects manager (body).                                     */
 /*                                                                         */
-/*  Copyright 1996-2015 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,14 +591,22 @@
         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;
 
       /* if we are performing a simple font format check, exit immediately */
       /* (this is here for pure CFF)                                       */
       if ( face_index < 0 )
+      {
+        cffface->num_faces = (FT_Long)cff->num_faces;
         return FT_Err_Ok;
+      }
 
       cff->pshinter = pshinter;
       cff->psnames  = psnames;
@@ -622,22 +642,112 @@
         FT_TRACE4(( "SIDs\n" ));
 
         /* dump string index, including default strings for convenience */
-        for ( idx = 0; idx < cff->num_strings + 390; idx++ )
+        for ( idx = 0; idx <= 390; idx++ )
         {
           s = cff_index_get_sid_string( cff, idx );
           if ( s )
-            FT_TRACE4(("  %5d %s\n", idx, s ));
+            FT_TRACE4(( "  %5d %s\n", idx, s ));
+        }
+
+        /* In Multiple Master CFFs, two SIDs hold the Normalize Design  */
+        /* Vector (NDV) and Convert Design Vector (CDV) charstrings,    */
+        /* which may contain NULL bytes in the middle of the data, too. */
+        /* We thus access `cff->strings' directly.                      */
+        for ( idx = 1; idx < cff->num_strings; idx++ )
+        {
+          FT_Byte*    s1    = cff->strings[idx - 1];
+          FT_Byte*    s2    = cff->strings[idx];
+          FT_PtrDist  s1len = s2 - s1 - 1; /* without the final NULL byte */
+          FT_PtrDist  l;
+
+
+          FT_TRACE4(( "  %5d ", idx + 390 ));
+          for ( l = 0; l < s1len; l++ )
+            FT_TRACE4(( "%c", s1[l] ));
+          FT_TRACE4(( "\n" ));
+        }
+
+        /* print last element */
+        if ( cff->num_strings )
+        {
+          FT_Byte*    s1    = cff->strings[cff->num_strings - 1];
+          FT_Byte*    s2    = cff->string_pool + cff->string_pool_size;
+          FT_PtrDist  s1len = s2 - s1 - 1;
+          FT_PtrDist  l;
+
+
+          FT_TRACE4(( "  %5d ", cff->num_strings + 390 ));
+          for ( l = 0; l < s1len; l++ )
+            FT_TRACE4(( "%c", s1[l] ));
+          FT_TRACE4(( "\n" ));
         }
       }
 #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;
 
-      /* Normalize the font matrix so that `matrix->yy' is 1; the */
-      /* scaling is done with `units_per_em' then (at this point, */
-      /* it already contains the scaling factor, but without      */
-      /* normalization of the matrix).                            */
+      /* Normalize the font matrix so that `matrix->yy' is 1; if  */
+      /* it is zero, we use `matrix->yx' instead.  The scaling is */
+      /* done with `units_per_em' then (at this point, it already */
+      /* contains the scaling factor, but without normalization   */
+      /* of the matrix).                                          */
       /*                                                          */
       /* Note that the offsets must be expressed in integer font  */
       /* units.                                                   */
@@ -646,9 +756,12 @@
         FT_Matrix*  matrix = &dict->font_matrix;
         FT_Vector*  offset = &dict->font_offset;
         FT_ULong*   upm    = &dict->units_per_em;
-        FT_Fixed    temp   = FT_ABS( matrix->yy );
+        FT_Fixed    temp;
 
 
+        temp = matrix->yy ? FT_ABS( matrix->yy )
+                          : FT_ABS( matrix->yx );
+
         if ( temp != 0x10000L )
         {
           *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp );
@@ -716,7 +829,10 @@
         matrix = &sub->font_matrix;
         offset = &sub->font_offset;
         upm    = &sub->units_per_em;
-        temp   = FT_ABS( matrix->yy );
+
+        temp = matrix->yy ? FT_ABS( matrix->yy )
+                          : FT_ABS( matrix->yx );
+
 
         if ( temp != 0x10000L )
         {
@@ -968,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:
@@ -1036,6 +1152,11 @@
         FT_FREE( face->extra.data );
       }
     }
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    cff_done_blend( face );
+    face->blend = NULL;
+#endif
   }
 
 
@@ -1052,7 +1173,7 @@
     driver->hinting_engine = FT_CFF_HINTING_ADOBE;
 #endif
 
-    driver->no_stem_darkening = FALSE;
+    driver->no_stem_darkening = TRUE;
 
     driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1;
     driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1;
diff --git a/third_party/freetype/src/cff/cffobjs.h b/third_party/freetype/src/cff/cffobjs.h
index 3cc9531..5d26977 100644
--- a/third_party/freetype/src/cff/cffobjs.h
+++ b/third_party/freetype/src/cff/cffobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType objects manager (specification).                            */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __CFFOBJS_H__
-#define __CFFOBJS_H__
+#ifndef CFFOBJS_H_
+#define CFFOBJS_H_
 
 
 #include <ft2build.h>
@@ -179,7 +179,7 @@
 
 FT_END_HEADER
 
-#endif /* __CFFOBJS_H__ */
+#endif /* CFFOBJS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cffparse.c b/third_party/freetype/src/cff/cffparse.c
index 063b351..819332b 100644
--- a/third_party/freetype/src/cff/cffparse.c
+++ b/third_party/freetype/src/cff/cffparse.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF token stream parser (body)                                       */
 /*                                                                         */
-/*  Copyright 1996-2015 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,6 +23,8 @@
 
 #include "cfferrs.h"
 #include "cffpic.h"
+#include "cffgload.h"
+#include "cffload.h"
 
 
   /*************************************************************************/
@@ -35,18 +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_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 );
   }
 
 
@@ -397,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 )
@@ -442,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 );
   }
 
 
@@ -462,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;
@@ -516,7 +585,11 @@
 
     if ( parser->top >= parser->stack + 6 )
     {
-      FT_Long  scaling;
+      FT_Fixed  values[6];
+      FT_Long   scalings[6];
+
+      FT_Long  min_scaling, max_scaling;
+      int      i;
 
 
       error = FT_Err_Ok;
@@ -525,22 +598,36 @@
 
       /* We expect a well-formed font matrix, this is, the matrix elements */
       /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
-      /* loss of precision, we use the magnitude of element `xx' to scale  */
-      /* all other elements.  The scaling factor is then contained in the  */
-      /* `units_per_em' value.                                             */
+      /* loss of precision, we use the magnitude of the largest matrix     */
+      /* element to scale all other elements.  The scaling factor is then  */
+      /* contained in the `units_per_em' value.                            */
 
-      matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
+      max_scaling = FT_LONG_MIN;
+      min_scaling = FT_LONG_MAX;
 
-      scaling = -scaling;
+      for ( i = 0; i < 6; i++ )
+      {
+        values[i] = cff_parse_fixed_dynamic( parser, data++, &scalings[i] );
+        if ( values[i] )
+        {
+          if ( scalings[i] > max_scaling )
+            max_scaling = scalings[i];
+          if ( scalings[i] < min_scaling )
+            min_scaling = scalings[i];
+        }
+      }
 
-      if ( scaling < 0 || scaling > 9 )
+      if ( max_scaling < -9                  ||
+           max_scaling > 0                   ||
+           ( max_scaling - min_scaling ) < 0 ||
+           ( max_scaling - min_scaling ) > 9 )
       {
         /* Return default matrix in case of unlikely values. */
 
         FT_TRACE1(( "cff_parse_font_matrix:"
-                    " strange scaling value for xx element (%d),\n"
+                    " strange scaling values (minimum %d, maximum %d),\n"
                     "                      "
-                    " using default matrix\n", scaling ));
+                    " using default matrix\n", min_scaling, max_scaling ));
 
         matrix->xx = 0x10000L;
         matrix->yx = 0;
@@ -553,13 +640,42 @@
         goto Exit;
       }
 
-      matrix->yx = cff_parse_fixed_scaled( data++, scaling );
-      matrix->xy = cff_parse_fixed_scaled( data++, scaling );
-      matrix->yy = cff_parse_fixed_scaled( data++, scaling );
-      offset->x  = cff_parse_fixed_scaled( data++, scaling );
-      offset->y  = cff_parse_fixed_scaled( data,   scaling );
+      for ( i = 0; i < 6; i++ )
+      {
+        FT_Fixed  value = values[i];
+        FT_Long   divisor, half_divisor;
 
-      *upm = (FT_ULong)power_tens[scaling];
+
+        if ( !value )
+          continue;
+
+        divisor      = power_tens[max_scaling - scalings[i]];
+        half_divisor = divisor >> 1;
+
+        if ( value < 0 )
+        {
+          if ( FT_LONG_MIN + half_divisor < value )
+            values[i] = ( value - half_divisor ) / divisor;
+          else
+            values[i] = FT_LONG_MIN / divisor;
+        }
+        else
+        {
+          if ( FT_LONG_MAX - half_divisor > value )
+            values[i] = ( value + half_divisor ) / divisor;
+          else
+            values[i] = FT_LONG_MAX / divisor;
+        }
+      }
+
+      matrix->xx = values[0];
+      matrix->yx = values[1];
+      matrix->xy = values[2];
+      matrix->yy = values[3];
+      offset->x  = values[4];
+      offset->y  = values[5];
+
+      *upm = (FT_ULong)power_tens[-max_scaling];
 
       FT_TRACE4(( " [%f %f %f %f %f %f]\n",
                   (double)matrix->xx / *upm / 65536,
@@ -588,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",
@@ -620,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" ));
@@ -629,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" ));
@@ -649,6 +765,56 @@
   }
 
 
+  /* The `MultipleMaster' operator comes before any  */
+  /* top DICT operators that contain T2 charstrings. */
+
+  static FT_Error
+  cff_parse_multiple_master( CFF_Parser  parser )
+  {
+    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
+    FT_Error         error;
+
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+    /* beautify tracing message */
+    if ( ft_trace_levels[FT_COMPONENT] < 4 )
+      FT_TRACE1(( "Multiple Master CFFs not supported yet,"
+                  " handling first master design only\n" ));
+    else
+      FT_TRACE1(( " (not supported yet,"
+                  " handling first master design only)\n" ));
+#endif
+
+    error = FT_ERR( Stack_Underflow );
+
+    /* currently, we handle only the first argument */
+    if ( parser->top >= parser->stack + 5 )
+    {
+      FT_Long  num_designs = cff_parse_num( parser, parser->stack );
+
+
+      if ( num_designs > 16 || num_designs < 2 )
+      {
+        FT_ERROR(( "cff_parse_multiple_master:"
+                   " Invalid number of designs\n" ));
+        error = FT_THROW( Invalid_File_Format );
+      }
+      else
+      {
+        dict->num_designs   = (FT_UShort)num_designs;
+        dict->num_axes      = (FT_UShort)( parser->top - parser->stack - 4 );
+
+        parser->num_designs = dict->num_designs;
+        parser->num_axes    = dict->num_axes;
+
+        error = FT_Err_Ok;
+      }
+    }
+
+    return error;
+  }
+
+
   static FT_Error
   cff_parse_cid_ros( CFF_Parser  parser )
   {
@@ -661,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 ));
@@ -681,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 )             \
@@ -692,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
 
@@ -715,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,                         \
@@ -758,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,                         \
@@ -965,14 +1266,16 @@
     {
       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;
+        *parser->top++ = p;
 
         /* now, skip it */
         if ( v == 30 )
@@ -1001,19 +1304,153 @@
         else if ( v > 246 )
           p += 1;
       }
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+      else if ( v == 31 )
+      {
+        /* a Type 2 charstring */
+
+        CFF_Decoder  decoder;
+        CFF_FontRec  cff_rec;
+        FT_Byte*     charstring_base;
+        FT_ULong     charstring_len;
+
+        FT_Fixed*  stack;
+        FT_Byte*   q;
+
+
+        charstring_base = ++p;
+
+        /* search `endchar' operator */
+        for (;;)
+        {
+          if ( p >= limit )
+            goto Exit;
+          if ( *p == 14 )
+            break;
+          p++;
+        }
+
+        charstring_len = (FT_ULong)( p - charstring_base ) + 1;
+
+        /* construct CFF_Decoder object */
+        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;
+        decoder.cff                            = &cff_rec;
+
+        error = cff_decoder_parse_charstrings( &decoder,
+                                               charstring_base,
+                                               charstring_len,
+                                               1 );
+
+        /* Now copy the stack data in the temporary decoder object,    */
+        /* converting it back to charstring number representations     */
+        /* (this is ugly, I know).                                     */
+        /*                                                             */
+        /* We overwrite the original top DICT charstring under the     */
+        /* assumption that the charstring representation of the result */
+        /* of `cff_decoder_parse_charstrings' is shorter, which should */
+        /* be always true.                                             */
+
+        q     = charstring_base - 1;
+        stack = decoder.stack;
+
+        while ( stack < decoder.top )
+        {
+          FT_ULong  num;
+          FT_Bool   neg;
+
+
+          if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
+            goto Stack_Overflow;
+
+          *parser->top++ = q;
+
+          if ( *stack < 0 )
+          {
+            num = (FT_ULong)-*stack;
+            neg = 1;
+          }
+          else
+          {
+            num = (FT_ULong)*stack;
+            neg = 0;
+          }
+
+          if ( num & 0xFFFFU )
+          {
+            if ( neg )
+              num = (FT_ULong)-num;
+
+            *q++ = 255;
+            *q++ = ( num & 0xFF000000U ) >> 24;
+            *q++ = ( num & 0x00FF0000U ) >> 16;
+            *q++ = ( num & 0x0000FF00U ) >>  8;
+            *q++ =   num & 0x000000FFU;
+          }
+          else
+          {
+            num >>= 16;
+
+            if ( neg )
+            {
+              if ( num <= 107 )
+                *q++ = (FT_Byte)( 139 - num );
+              else if ( num <= 1131 )
+              {
+                *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 );
+                *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
+              }
+              else
+              {
+                num = (FT_ULong)-num;
+
+                *q++ = 28;
+                *q++ = (FT_Byte)( num >> 8 );
+                *q++ = (FT_Byte)( num & 0xFF );
+              }
+            }
+            else
+            {
+              if ( num <= 107 )
+                *q++ = (FT_Byte)( num + 139 );
+              else if ( num <= 1131 )
+              {
+                *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 );
+                *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
+              }
+              else
+              {
+                *q++ = 28;
+                *q++ = (FT_Byte)( num >> 8 );
+                *q++ = (FT_Byte)( num & 0xFF );
+              }
+            }
+          }
+
+          stack++;
+        }
+      }
+#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
       else
       {
         /* This is not a number, hence it's an operator.  Compute its code */
         /* 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 */
@@ -1048,15 +1485,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 )
@@ -1125,7 +1562,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):
@@ -1154,7 +1591,7 @@
               }
               break;
 
-            default:  /* callback */
+            default:  /* callback or blend */
               error = field->reader( parser );
               if ( error )
                 goto Exit;
@@ -1168,7 +1605,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/third_party/freetype/src/cff/cffparse.h b/third_party/freetype/src/cff/cffparse.h
index 8ad02ea..9976d42 100644
--- a/third_party/freetype/src/cff/cffparse.h
+++ b/third_party/freetype/src/cff/cffparse.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF token stream parser (specification)                              */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __CFF_PARSE_H__
-#define __CFF_PARSE_H__
+#ifndef CFFPARSE_H_
+#define CFFPARSE_H_
 
 
 #include <ft2build.h>
@@ -28,33 +28,54 @@
 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_
   {
-    FT_Library library;
-    FT_Byte*   start;
-    FT_Byte*   limit;
-    FT_Byte*   cursor;
+    FT_Library  library;
+    FT_Byte*    start;
+    FT_Byte*    limit;
+    FT_Byte*    cursor;
 
-    FT_Byte*   stack[CFF_MAX_STACK_DEPTH + 1];
-    FT_Byte**  top;
+    FT_Byte**   stack;
+    FT_Byte**   top;
+    FT_UInt     stackSize;  /* allocated size */
 
-    FT_UInt    object_code;
-    void*      object;
+    FT_UInt     object_code;
+    void*       object;
+
+    FT_UShort   num_designs; /* a copy of `CFF_FontRecDict->num_designs' */
+    FT_UShort   num_axes;    /* a copy of `CFF_FontRecDict->num_axes'    */
 
   } 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_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,
@@ -72,6 +93,7 @@
     cff_kind_bool,
     cff_kind_delta,
     cff_kind_callback,
+    cff_kind_blend,
 
     cff_kind_max  /* do not remove */
   };
@@ -100,7 +122,7 @@
 FT_END_HEADER
 
 
-#endif /* __CFF_PARSE_H__ */
+#endif /* CFFPARSE_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cffpic.c b/third_party/freetype/src/cff/cffpic.c
index d40dec5..4e9ba12 100644
--- a/third_party/freetype/src/cff/cffpic.c
+++ b/third_party/freetype/src/cff/cffpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for cff module.      */
 /*                                                                         */
-/*  Copyright 2009-2015 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/third_party/freetype/src/cff/cffpic.h b/third_party/freetype/src/cff/cffpic.h
index 9a221a7..0b89fcb 100644
--- a/third_party/freetype/src/cff/cffpic.h
+++ b/third_party/freetype/src/cff/cffpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for cff module.      */
 /*                                                                         */
-/*  Copyright 2009-2015 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __CFFPIC_H__
-#define __CFFPIC_H__
+#ifndef CFFPIC_H_
+#define CFFPIC_H_
 
 
 #include FT_INTERNAL_PIC_H
@@ -32,6 +32,7 @@
 #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_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
@@ -102,7 +103,7 @@
 
  /* */
 
-#endif /* __CFFPIC_H__ */
+#endif /* CFFPIC_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cff/cfftoken.h b/third_party/freetype/src/cff/cfftoken.h
index 5b32076..3222e93 100644
--- a/third_party/freetype/src/cff/cfftoken.h
+++ b/third_party/freetype/src/cff/cfftoken.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF token definitions (specification only).                          */
 /*                                                                         */
-/*  Copyright 1996-2015 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" )
@@ -38,6 +38,9 @@
   CFF_FIELD_NUM     ( 13,    unique_id,           "UniqueID" )
   CFF_FIELD_CALLBACK( 5,     font_bbox,           "FontBBox" )
   CFF_FIELD_NUM     ( 0x108, stroke_width,        "StrokeWidth" )
+#if 0
+  CFF_FIELD_DELTA   ( 14,    xuid, 16,            "XUID" )
+#endif
   CFF_FIELD_NUM     ( 15,    charset_offset,      "charset" )
   CFF_FIELD_NUM     ( 16,    encoding_offset,     "Encoding" )
   CFF_FIELD_NUM     ( 17,    charstrings_offset,  "CharStrings" )
@@ -48,8 +51,13 @@
 #if 0
   CFF_FIELD_STRING  ( 0x116, base_font_name,      "BaseFontName" )
   CFF_FIELD_DELTA   ( 0x117, base_font_blend, 16, "BaseFontBlend" )
+#endif
+
+  /* the next two operators were removed from the Type2 specification */
+  /* in version 16-March-2000                                         */
   CFF_FIELD_CALLBACK( 0x118, multiple_master,     "MultipleMaster" )
-  CFF_FIELD_CALLBACK( 0x119, blend_axis_types,    "BlendAxisTypes" )
+#if 0
+  CFF_FIELD_CALLBACK( 0x11A, blend_axis_types,    "BlendAxisTypes" )
 #endif
 
   CFF_FIELD_CALLBACK( 0x11E, cid_ros,              "ROS" )
@@ -70,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" )
@@ -94,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/third_party/freetype/src/cff/cfftypes.h b/third_party/freetype/src/cff/cfftypes.h
index de8a5ee..412712c 100644
--- a/third_party/freetype/src/cff/cfftypes.h
+++ b/third_party/freetype/src/cff/cfftypes.h
@@ -5,7 +5,7 @@
 /*    Basic OpenType/CFF type definitions and interface (specification     */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -17,8 +17,8 @@
 /***************************************************************************/
 
 
-#ifndef __CFFTYPES_H__
-#define __CFFTYPES_H__
+#ifndef CFFTYPES_H_
+#define CFFTYPES_H_
 
 
 #include <ft2build.h>
@@ -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;
@@ -145,9 +219,23 @@
     FT_ULong   cid_fd_select_offset;
     FT_UInt    cid_font_name;
 
+    /* the next fields come from the data of the deprecated          */
+    /* `MultipleMaster' operator; they are needed to parse the (also */
+    /* deprecated) `blend' operator in Type 2 charstrings            */
+    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;
@@ -180,6 +268,10 @@
     FT_Pos    default_width;
     FT_Pos    nominal_width;
 
+    /* fields for CFF2 */
+    FT_UInt      vsindex;
+    CFF_SubFont  subfont;
+
   } CFF_PrivateRec, *CFF_Private;
 
 
@@ -207,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
@@ -218,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;
@@ -250,6 +365,7 @@
     FT_UInt          num_strings;
     FT_Byte**        strings;
     FT_Byte*         string_pool;
+    FT_ULong         string_pool_size;
 
     CFF_SubFontRec   top_font;
     FT_UInt          num_subfonts;
@@ -273,12 +389,14 @@
     /* since version 2.4.12 */
     FT_Generic       cf2_instance;
 
-  } CFF_FontRec, *CFF_Font;
+    CFF_VStoreRec    vstore;        /* parsed vstore structure */
+
+  } CFF_FontRec;
 
 
 FT_END_HEADER
 
-#endif /* __CFFTYPES_H__ */
+#endif /* CFFTYPES_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cid/ciderrs.h b/third_party/freetype/src/cid/ciderrs.h
index 5e0e776..709dc8c 100644
--- a/third_party/freetype/src/cid/ciderrs.h
+++ b/third_party/freetype/src/cid/ciderrs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CID error codes (specification only).                                */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -22,12 +22,12 @@
   /*                                                                       */
   /*************************************************************************/
 
-#ifndef __CIDERRS_H__
-#define __CIDERRS_H__
+#ifndef CIDERRS_H_
+#define CIDERRS_H_
 
 #include FT_MODULE_ERRORS_H
 
-#undef __FTERRORS_H__
+#undef FTERRORS_H_
 
 #undef  FT_ERR_PREFIX
 #define FT_ERR_PREFIX  CID_Err_
@@ -35,7 +35,7 @@
 
 #include FT_ERRORS_H
 
-#endif /* __CIDERRS_H__ */
+#endif /* CIDERRS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cid/cidgload.c b/third_party/freetype/src/cid/cidgload.c
index d00674f..b96c333 100644
--- a/third_party/freetype/src/cid/cidgload.c
+++ b/third_party/freetype/src/cid/cidgload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CID-keyed Type1 Glyph Loader (body).                                 */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -100,7 +100,7 @@
     /* and charstring offset from the CIDMap.                */
     {
       FT_UInt   entry_len = (FT_UInt)( cid->fd_bytes + cid->gd_bytes );
-      FT_ULong  off1;
+      FT_ULong  off1, off2;
 
 
       if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
@@ -108,18 +108,23 @@
            FT_FRAME_ENTER( 2 * entry_len )                         )
         goto Exit;
 
-      p            = (FT_Byte*)stream->cursor;
-      fd_select    = cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
-      off1         = cid_get_offset( &p, (FT_Byte)cid->gd_bytes );
-      p           += cid->fd_bytes;
-      glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1;
+      p         = (FT_Byte*)stream->cursor;
+      fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
+      off1      = cid_get_offset( &p, (FT_Byte)cid->gd_bytes );
+      p        += cid->fd_bytes;
+      off2      = cid_get_offset( &p, (FT_Byte)cid->gd_bytes );
       FT_FRAME_EXIT();
 
-      if ( fd_select >= (FT_ULong)cid->num_dicts )
+      if ( fd_select >= (FT_ULong)cid->num_dicts ||
+           off2 > stream->size                   ||
+           off1 > off2                           )
       {
+        FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" ));
         error = FT_THROW( Invalid_Offset );
         goto Exit;
       }
+
+      glyph_length = off2 - off1;
       if ( glyph_length == 0 )
         goto Exit;
       if ( FT_ALLOC( charstring, glyph_length ) )
@@ -137,9 +142,10 @@
 
 
       /* Set up subrs */
-      decoder->num_subrs = cid_subrs->num_subrs;
-      decoder->subrs     = cid_subrs->code;
-      decoder->subrs_len = 0;
+      decoder->num_subrs  = cid_subrs->num_subrs;
+      decoder->subrs      = cid_subrs->code;
+      decoder->subrs_len  = 0;
+      decoder->subrs_hash = NULL;
 
       /* Set up font matrix */
       dict                 = cid->font_dicts + fd_select;
@@ -152,6 +158,12 @@
 
       /* Adjustment for seed bytes. */
       cs_offset = decoder->lenIV >= 0 ? (FT_UInt)decoder->lenIV : 0;
+      if ( cs_offset > glyph_length )
+      {
+        FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" ));
+        error = FT_THROW( Invalid_Offset );
+        goto Exit;
+      }
 
       /* Decrypt only if lenIV >= 0. */
       if ( decoder->lenIV >= 0 )
@@ -162,8 +174,6 @@
                 glyph_length - cs_offset );
     }
 
-    FT_FREE( charstring );
-
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
 
     /* Incremental fonts can optionally override the metrics. */
@@ -188,6 +198,8 @@
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
 
   Exit:
+    FT_FREE( charstring );
+
     return error;
   }
 
diff --git a/third_party/freetype/src/cid/cidgload.h b/third_party/freetype/src/cid/cidgload.h
index 4a10ce5..7f816b5 100644
--- a/third_party/freetype/src/cid/cidgload.h
+++ b/third_party/freetype/src/cid/cidgload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType Glyph Loader (specification).                               */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __CIDGLOAD_H__
-#define __CIDGLOAD_H__
+#ifndef CIDGLOAD_H_
+#define CIDGLOAD_H_
 
 
 #include <ft2build.h>
@@ -45,7 +45,7 @@
 
 FT_END_HEADER
 
-#endif /* __CIDGLOAD_H__ */
+#endif /* CIDGLOAD_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cid/cidload.c b/third_party/freetype/src/cid/cidload.c
index e23b82f..ff07221 100644
--- a/third_party/freetype/src/cid/cidload.c
+++ b/third_party/freetype/src/cid/cidload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CID-keyed Type1 font loader (body).                                  */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -215,6 +215,7 @@
   {
     CID_FaceInfo  cid    = &face->cid;
     FT_Memory     memory = face->root.memory;
+    FT_Stream     stream = parser->stream;
     FT_Error      error  = FT_Err_Ok;
     FT_Long       num_dicts;
 
@@ -227,6 +228,31 @@
       goto Exit;
     }
 
+    /*
+     * A single entry in the FDArray must (at least) contain the following
+     * structure elements.
+     *
+     *   %ADOBeginFontDict              18
+     *   X dict begin                   13
+     *     /FontMatrix [X X X X]        22
+     *     /Private X dict begin        22
+     *     end                           4
+     *   end                             4
+     *   %ADOEndFontDict                16
+     *
+     * This needs 18+13+22+22+4+4+16=99 bytes or more.  Normally, you also
+     * need a `dup X' at the very beginning and a `put' at the end, so a
+     * rough guess using 100 bytes as the minimum is justified.
+     */
+    if ( (FT_ULong)num_dicts > stream->size / 100 )
+    {
+      FT_TRACE0(( "parse_fd_array: adjusting FDArray size"
+                  " (from %d to %d)\n",
+                  num_dicts,
+                  stream->size / 100 ));
+      num_dicts = (FT_Long)( stream->size / 100 );
+    }
+
     if ( !cid->font_dicts )
     {
       FT_Int  n;
@@ -395,7 +421,14 @@
 
         cur = parser->root.cursor;
       }
+
+      if ( !face->cid.num_dicts )
+      {
+        FT_ERROR(( "cid_parse_dict: No font dictionary found\n" ));
+        return FT_THROW( Invalid_File_Format );
+      }
     }
+
     return parser->root.error;
   }
 
@@ -428,12 +461,8 @@
       FT_Byte*      p;
 
 
-      /* Check for possible overflow. */
-      if ( num_subrs == FT_UINT_MAX )
-      {
-        error = FT_THROW( Syntax_Error );
-        goto Fail;
-      }
+      if ( !num_subrs )
+        continue;
 
       /* reallocate offsets array if needed */
       if ( num_subrs + 1 > max_offsets )
@@ -467,14 +496,25 @@
       /* offsets must be ordered */
       for ( count = 1; count <= num_subrs; count++ )
         if ( offsets[count - 1] > offsets[count] )
+        {
+          FT_ERROR(( "cid_read_subrs: offsets are not ordered\n" ));
+          error = FT_THROW( Invalid_File_Format );
           goto Fail;
+        }
+
+      if ( offsets[num_subrs] > stream->size - cid->data_offset )
+      {
+        FT_ERROR(( "cid_read_subrs: too large `subrs' offsets\n" ));
+        error = FT_THROW( Invalid_File_Format );
+        goto Fail;
+      }
 
       /* now, compute the size of subrs charstrings, */
       /* allocate, and read them                     */
       data_len = offsets[num_subrs] - offsets[0];
 
       if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) ||
-               FT_ALLOC( subr->code[0], data_len )   )
+           FT_ALLOC( subr->code[0], data_len )       )
         goto Fail;
 
       if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) ||
@@ -533,7 +573,7 @@
   {
     FT_UNUSED( face );
 
-    FT_MEM_ZERO( loader, sizeof ( *loader ) );
+    FT_ZERO( loader );
   }
 
 
@@ -654,6 +694,12 @@
     CID_Parser*  parser;
     FT_Memory    memory = face->root.memory;
     FT_Error     error;
+    FT_Int       n;
+
+    CID_FaceInfo  cid = &face->cid;
+
+    FT_ULong  binary_length;
+    FT_ULong  entry_len;
 
 
     cid_init_loader( &loader, face );
@@ -678,22 +724,117 @@
 
     if ( parser->binary_length )
     {
+      if ( parser->binary_length >
+             face->root.stream->size - parser->data_offset )
+      {
+        FT_TRACE0(( "cid_face_open: adjusting length of binary data\n"
+                    "               (from %d to %d bytes)\n",
+                    parser->binary_length,
+                    face->root.stream->size - parser->data_offset ));
+        parser->binary_length = face->root.stream->size -
+                                parser->data_offset;
+      }
+
       /* we must convert the data section from hexadecimal to binary */
-      if ( FT_ALLOC( face->binary_data, parser->binary_length )         ||
-           cid_hex_to_binary( face->binary_data, parser->binary_length,
-                              parser->data_offset, face )               )
+      if ( FT_ALLOC( face->binary_data, parser->binary_length )    ||
+           FT_SET_ERROR( cid_hex_to_binary( face->binary_data,
+                                            parser->binary_length,
+                                            parser->data_offset,
+                                            face ) )               )
         goto Exit;
 
       FT_Stream_OpenMemory( face->cid_stream,
                             face->binary_data, parser->binary_length );
-      face->cid.data_offset = 0;
+      cid->data_offset = 0;
     }
     else
     {
-      *face->cid_stream     = *face->root.stream;
-      face->cid.data_offset = loader.parser.data_offset;
+      *face->cid_stream = *face->root.stream;
+      cid->data_offset  = loader.parser.data_offset;
     }
 
+    /* sanity tests */
+
+    if ( cid->fd_bytes < 0 || cid->gd_bytes < 1 )
+    {
+      FT_ERROR(( "cid_parse_dict:"
+                 " Invalid `FDBytes' or `GDBytes' value\n" ));
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
+    }
+
+    /* allow at most 32bit offsets */
+    if ( cid->fd_bytes > 4 || cid->gd_bytes > 4 )
+    {
+      FT_ERROR(( "cid_parse_dict:"
+                 " Values of `FDBytes' or `GDBytes' larger than 4\n"
+                 "               "
+                 " are not supported\n" ));
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
+    }
+
+    binary_length = face->cid_stream->size - cid->data_offset;
+    entry_len     = (FT_ULong)( cid->fd_bytes + cid->gd_bytes );
+
+    for ( n = 0; n < cid->num_dicts; n++ )
+    {
+      CID_FaceDict  dict = cid->font_dicts + n;
+
+
+      if ( dict->sd_bytes < 0                        ||
+           ( dict->num_subrs && dict->sd_bytes < 1 ) )
+      {
+        FT_ERROR(( "cid_parse_dict: Invalid `SDBytes' value\n" ));
+        error = FT_THROW( Invalid_File_Format );
+        goto Exit;
+      }
+
+      if ( dict->sd_bytes > 4 )
+      {
+        FT_ERROR(( "cid_parse_dict:"
+                   " Values of `SDBytes' larger than 4"
+                   " are not supported\n" ));
+        error = FT_THROW( Invalid_File_Format );
+        goto Exit;
+      }
+
+      if ( dict->subrmap_offset > binary_length )
+      {
+        FT_ERROR(( "cid_parse_dict: Invalid `SubrMapOffset' value\n" ));
+        error = FT_THROW( Invalid_File_Format );
+        goto Exit;
+      }
+
+      /* `num_subrs' is scanned as a signed integer */
+      if ( (FT_Int)dict->num_subrs < 0                                     ||
+           ( dict->sd_bytes                                              &&
+             dict->num_subrs > ( binary_length - dict->subrmap_offset ) /
+                                 (FT_UInt)dict->sd_bytes                 ) )
+      {
+        FT_ERROR(( "cid_parse_dict: Invalid `SubrCount' value\n" ));
+        error = FT_THROW( Invalid_File_Format );
+        goto Exit;
+      }
+    }
+
+    if ( cid->cidmap_offset > binary_length )
+    {
+      FT_ERROR(( "cid_parse_dict: Invalid `CIDMapOffset' value\n" ));
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
+    }
+
+    if ( entry_len                                            &&
+         cid->cid_count >
+           ( binary_length - cid->cidmap_offset ) / entry_len )
+    {
+      FT_ERROR(( "cid_parse_dict: Invalid `CIDCount' value\n" ));
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
+    }
+
+    /* we can now safely proceed */
     error = cid_read_subrs( face );
 
   Exit:
diff --git a/third_party/freetype/src/cid/cidload.h b/third_party/freetype/src/cid/cidload.h
index d7776d2..45a0e6d 100644
--- a/third_party/freetype/src/cid/cidload.h
+++ b/third_party/freetype/src/cid/cidload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CID-keyed Type1 font loader (specification).                         */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __CIDLOAD_H__
-#define __CIDLOAD_H__
+#ifndef CIDLOAD_H_
+#define CIDLOAD_H_
 
 
 #include <ft2build.h>
@@ -47,7 +47,7 @@
 
 FT_END_HEADER
 
-#endif /* __CIDLOAD_H__ */
+#endif /* CIDLOAD_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cid/cidobjs.c b/third_party/freetype/src/cid/cidobjs.c
index bf1519b..7830e1f 100644
--- a/third_party/freetype/src/cid/cidobjs.c
+++ b/third_party/freetype/src/cid/cidobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CID objects manager (body).                                          */
 /*                                                                         */
-/*  Copyright 1996-2015 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/third_party/freetype/src/cid/cidobjs.h b/third_party/freetype/src/cid/cidobjs.h
index e9095ca..8bcf886 100644
--- a/third_party/freetype/src/cid/cidobjs.h
+++ b/third_party/freetype/src/cid/cidobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CID objects manager (specification).                                 */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __CIDOBJS_H__
-#define __CIDOBJS_H__
+#ifndef CIDOBJS_H_
+#define CIDOBJS_H_
 
 
 #include <ft2build.h>
@@ -148,7 +148,7 @@
 
 FT_END_HEADER
 
-#endif /* __CIDOBJS_H__ */
+#endif /* CIDOBJS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cid/cidparse.c b/third_party/freetype/src/cid/cidparse.c
index c276949..007609b 100644
--- a/third_party/freetype/src/cid/cidparse.c
+++ b/third_party/freetype/src/cid/cidparse.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CID-keyed Type1 parser (body).                                       */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -47,6 +47,12 @@
   /*************************************************************************/
 
 
+#define STARTDATA      "StartData"
+#define STARTDATA_LEN  ( sizeof ( STARTDATA ) - 1 )
+#define SFNTS          "/sfnts"
+#define SFNTS_LEN      ( sizeof ( SFNTS ) - 1 )
+
+
   FT_LOCAL_DEF( FT_Error )
   cid_parser_new( CID_Parser*    parser,
                   FT_Stream      stream,
@@ -59,7 +65,7 @@
     FT_Byte   *arg1, *arg2;
 
 
-    FT_MEM_ZERO( parser, sizeof ( *parser ) );
+    FT_ZERO( parser );
     psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );
 
     parser->stream = stream;
@@ -85,9 +91,29 @@
     /* now, read the rest of the file until we find */
     /* `StartData' or `/sfnts'                      */
     {
-      FT_Byte   buffer[256 + 10];
-      FT_ULong  read_len = 256 + 10;
-      FT_Byte*  p        = buffer;
+      /*
+       * The algorithm is as follows (omitting the case with less than 256
+       * bytes to fill for simplicity).
+       *
+       * 1. Fill the buffer with 256 + STARTDATA_LEN bytes.
+       *
+       * 2. Search for the STARTDATA and SFNTS strings at positions
+       *    buffer[0], buffer[1], ...,
+       *    buffer[255 + STARTDATA_LEN - SFNTS_LEN].
+       *
+       * 3. Move the last STARTDATA_LEN bytes to buffer[0].
+       *
+       * 4. Fill the buffer with 256 bytes, starting at STARTDATA_LEN.
+       *
+       * 5. Repeat with step 2.
+       *
+       */
+      FT_Byte  buffer[256 + STARTDATA_LEN + 1];
+
+      /* values for the first loop */
+      FT_ULong  read_len    = 256 + STARTDATA_LEN;
+      FT_ULong  read_offset = 0;
+      FT_Byte*  p           = buffer;
 
 
       for ( offset = FT_STREAM_POS(); ; offset += 256 )
@@ -96,40 +122,48 @@
 
 
         stream_len = stream->size - FT_STREAM_POS();
-        if ( stream_len == 0 )
+
+        read_len = FT_MIN( read_len, stream_len );
+        if ( FT_STREAM_READ( p, read_len ) )
+          goto Exit;
+
+        /* ensure that we do not compare with data beyond the buffer */
+        p[read_len] = '\0';
+
+        limit = p + read_len - SFNTS_LEN;
+
+        for ( p = buffer; p < limit; p++ )
+        {
+          if ( p[0] == 'S'                                           &&
+               ft_strncmp( (char*)p, STARTDATA, STARTDATA_LEN ) == 0 )
+          {
+            /* save offset of binary data after `StartData' */
+            offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN + 1;
+            goto Found;
+          }
+          else if ( p[1] == 's'                                   &&
+                    ft_strncmp( (char*)p, SFNTS, SFNTS_LEN ) == 0 )
+          {
+            offset += (FT_ULong)( p - buffer ) + SFNTS_LEN + 1;
+            goto Found;
+          }
+        }
+
+        if ( read_offset + read_len < STARTDATA_LEN )
         {
           FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" ));
           error = FT_THROW( Invalid_File_Format );
           goto Exit;
         }
 
-        read_len = FT_MIN( read_len, stream_len );
-        if ( FT_STREAM_READ( p, read_len ) )
-          goto Exit;
+        FT_MEM_MOVE( buffer,
+                     buffer + read_offset + read_len - STARTDATA_LEN,
+                     STARTDATA_LEN );
 
-        if ( read_len < 256 )
-          p[read_len]  = '\0';
-
-        limit = p + read_len - 10;
-
-        for ( p = buffer; p < limit; p++ )
-        {
-          if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 )
-          {
-            /* save offset of binary data after `StartData' */
-            offset += (FT_ULong)( p - buffer + 10 );
-            goto Found;
-          }
-          else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 )
-          {
-            offset += (FT_ULong)( p - buffer + 7 );
-            goto Found;
-          }
-        }
-
-        FT_MEM_MOVE( buffer, p, 10 );
-        read_len = 256;
-        p = buffer + 10;
+        /* values for the next loop */
+        read_len    = 256;
+        read_offset = STARTDATA_LEN;
+        p           = buffer + read_offset;
       }
     }
 
@@ -165,7 +199,7 @@
     limit = parser->root.limit;
     cur   = parser->root.cursor;
 
-    while ( cur < limit )
+    while ( cur <= limit - SFNTS_LEN )
     {
       if ( parser->root.error )
       {
@@ -173,11 +207,13 @@
         goto Exit;
       }
 
-      if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
+      if ( cur[0] == 'S'                                           &&
+           cur <= limit - STARTDATA_LEN                            &&
+           ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 )
       {
         if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
         {
-          FT_Long  tmp = ft_atol( (const char *)arg2 );
+          FT_Long  tmp = ft_strtol( (const char *)arg2, NULL, 10 );
 
 
           if ( tmp < 0 )
@@ -191,7 +227,8 @@
 
         goto Exit;
       }
-      else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 )
+      else if ( cur[1] == 's'                                   &&
+                ft_strncmp( (char*)cur, SFNTS, SFNTS_LEN ) == 0 )
       {
         FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" ));
         error = FT_THROW( Unknown_File_Format );
@@ -216,6 +253,12 @@
   }
 
 
+#undef STARTDATA
+#undef STARTDATA_LEN
+#undef SFNTS
+#undef SFNTS_LEN
+
+
   FT_LOCAL_DEF( void )
   cid_parser_done( CID_Parser*  parser )
   {
diff --git a/third_party/freetype/src/cid/cidparse.h b/third_party/freetype/src/cid/cidparse.h
index f581bb4..20bebb9 100644
--- a/third_party/freetype/src/cid/cidparse.h
+++ b/third_party/freetype/src/cid/cidparse.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CID-keyed Type1 parser (specification).                              */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __CIDPARSE_H__
-#define __CIDPARSE_H__
+#ifndef CIDPARSE_H_
+#define CIDPARSE_H_
 
 
 #include <ft2build.h>
@@ -117,7 +117,7 @@
 
 FT_END_HEADER
 
-#endif /* __CIDPARSE_H__ */
+#endif /* CIDPARSE_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cid/cidriver.c b/third_party/freetype/src/cid/cidriver.c
index 07c4cc4..bb611a9 100644
--- a/third_party/freetype/src/cid/cidriver.c
+++ b/third_party/freetype/src/cid/cidriver.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CID driver interface (body).                                         */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -59,7 +59,7 @@
 
   static const FT_Service_PsFontNameRec  cid_service_ps_name =
   {
-    (FT_PsName_GetFunc) cid_get_postscript_name
+    (FT_PsName_GetFunc)cid_get_postscript_name    /* get_ps_font_name */
   };
 
 
@@ -88,11 +88,14 @@
 
   static const FT_Service_PsInfoRec  cid_service_ps_info =
   {
-    (PS_GetFontInfoFunc)   cid_ps_get_font_info,
-    (PS_GetFontExtraFunc)  cid_ps_get_font_extra,
-    (PS_HasGlyphNamesFunc) NULL,        /* unsupported with CID fonts */
-    (PS_GetFontPrivateFunc)NULL,        /* unsupported                */
-    (PS_GetFontValueFunc)  NULL         /* not implemented            */
+    (PS_GetFontInfoFunc)   cid_ps_get_font_info,   /* ps_get_font_info    */
+    (PS_GetFontExtraFunc)  cid_ps_get_font_extra,  /* ps_get_font_extra   */
+    /* unsupported with CID fonts */
+    (PS_HasGlyphNamesFunc) NULL,                   /* ps_has_glyph_names  */
+    /* unsupported                */
+    (PS_GetFontPrivateFunc)NULL,                   /* ps_get_font_private */
+    /* not implemented            */
+    (PS_GetFontValueFunc)  NULL                    /* ps_get_font_value   */
   };
 
 
@@ -155,9 +158,12 @@
 
   static const FT_Service_CIDRec  cid_service_cid_info =
   {
-     (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros,
-     (FT_CID_GetIsInternallyCIDKeyedFunc)      cid_get_is_cid,
-     (FT_CID_GetCIDFromGlyphIndexFunc)         cid_get_cid_from_glyph_index
+    (FT_CID_GetRegistryOrderingSupplementFunc)
+      cid_get_ros,                             /* get_ros                  */
+    (FT_CID_GetIsInternallyCIDKeyedFunc)
+      cid_get_is_cid,                          /* get_is_cid               */
+    (FT_CID_GetCIDFromGlyphIndexFunc)
+      cid_get_cid_from_glyph_index             /* get_cid_from_glyph_index */
   };
 
 
@@ -190,46 +196,42 @@
   FT_CALLBACK_TABLE_DEF
   const FT_Driver_ClassRec  t1cid_driver_class =
   {
-    /* first of all, the FT_Module_Class fields */
     {
       FT_MODULE_FONT_DRIVER       |
       FT_MODULE_DRIVER_SCALABLE   |
       FT_MODULE_DRIVER_HAS_HINTER,
-
       sizeof ( FT_DriverRec ),
+
       "t1cid",   /* module name           */
       0x10000L,  /* version 1.0 of driver */
       0x20000L,  /* requires FreeType 2.0 */
 
-      0,
+      NULL,    /* module-specific interface */
 
-      cid_driver_init,
-      cid_driver_done,
-      cid_get_interface
+      cid_driver_init,          /* FT_Module_Constructor  module_init   */
+      cid_driver_done,          /* FT_Module_Destructor   module_done   */
+      cid_get_interface         /* FT_Module_Requester    get_interface */
     },
 
-    /* then the other font drivers fields */
     sizeof ( CID_FaceRec ),
     sizeof ( CID_SizeRec ),
     sizeof ( CID_GlyphSlotRec ),
 
-    cid_face_init,
-    cid_face_done,
+    cid_face_init,              /* FT_Face_InitFunc  init_face */
+    cid_face_done,              /* FT_Face_DoneFunc  done_face */
+    cid_size_init,              /* FT_Size_InitFunc  init_size */
+    cid_size_done,              /* FT_Size_DoneFunc  done_size */
+    cid_slot_init,              /* FT_Slot_InitFunc  init_slot */
+    cid_slot_done,              /* FT_Slot_DoneFunc  done_slot */
 
-    cid_size_init,
-    cid_size_done,
-    cid_slot_init,
-    cid_slot_done,
+    cid_slot_load_glyph,        /* FT_Slot_LoadFunc  load_glyph */
 
-    cid_slot_load_glyph,
+    NULL,                       /* FT_Face_GetKerningFunc   get_kerning  */
+    NULL,                       /* FT_Face_AttachFunc       attach_file  */
+    NULL,                       /* FT_Face_GetAdvancesFunc  get_advances */
 
-    0,                      /* FT_Face_GetKerningFunc  */
-    0,                      /* FT_Face_AttachFunc      */
-
-    0,                      /* FT_Face_GetAdvancesFunc */
-
-    cid_size_request,
-    0                       /* FT_Size_SelectFunc      */
+    cid_size_request,           /* FT_Size_RequestFunc  request_size */
+    NULL                        /* FT_Size_SelectFunc   select_size  */
   };
 
 
diff --git a/third_party/freetype/src/cid/cidriver.h b/third_party/freetype/src/cid/cidriver.h
index e5b8678..76640c5 100644
--- a/third_party/freetype/src/cid/cidriver.h
+++ b/third_party/freetype/src/cid/cidriver.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level CID driver interface (specification).                     */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __CIDRIVER_H__
-#define __CIDRIVER_H__
+#ifndef CIDRIVER_H_
+#define CIDRIVER_H_
 
 
 #include <ft2build.h>
@@ -37,7 +37,7 @@
 
 FT_END_HEADER
 
-#endif /* __CIDRIVER_H__ */
+#endif /* CIDRIVER_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/cid/cidtoken.h b/third_party/freetype/src/cid/cidtoken.h
index 82eae0c..653cc55 100644
--- a/third_party/freetype/src/cid/cidtoken.h
+++ b/third_party/freetype/src/cid/cidtoken.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CID token definitions (specification only).                          */
 /*                                                                         */
-/*  Copyright 1996-2015 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/third_party/freetype/src/cid/type1cid.c b/third_party/freetype/src/cid/type1cid.c
index 0d54ca7..aeb9c3e 100644
--- a/third_party/freetype/src/cid/type1cid.c
+++ b/third_party/freetype/src/cid/type1cid.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType OpenType driver component (body only).                      */
 /*                                                                         */
-/*  Copyright 1996-2015 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/third_party/freetype/src/psaux/afmparse.c b/third_party/freetype/src/psaux/afmparse.c
index 3ad44ec..dbe7ddd 100644
--- a/third_party/freetype/src/psaux/afmparse.c
+++ b/third_party/freetype/src/psaux/afmparse.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    AFM parser (body).                                                   */
 /*                                                                         */
-/*  Copyright 2006-2015 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/third_party/freetype/src/psaux/afmparse.h b/third_party/freetype/src/psaux/afmparse.h
index f922c4e..cd2beb7 100644
--- a/third_party/freetype/src/psaux/afmparse.h
+++ b/third_party/freetype/src/psaux/afmparse.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    AFM parser (specification).                                          */
 /*                                                                         */
-/*  Copyright 2006-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __AFMPARSE_H__
-#define __AFMPARSE_H__
+#ifndef AFMPARSE_H_
+#define AFMPARSE_H_
 
 
 #include <ft2build.h>
@@ -83,7 +83,7 @@
 
 FT_END_HEADER
 
-#endif /* __AFMPARSE_H__ */
+#endif /* AFMPARSE_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/psaux/psaux.c b/third_party/freetype/src/psaux/psaux.c
index 7f1d9aa..f8f19d0 100644
--- a/third_party/freetype/src/psaux/psaux.c
+++ b/third_party/freetype/src/psaux/psaux.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType auxiliary PostScript driver component (body only).          */
 /*                                                                         */
-/*  Copyright 1996-2015 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/third_party/freetype/src/psaux/psauxerr.h b/third_party/freetype/src/psaux/psauxerr.h
index 97712f0..1d7ac60 100644
--- a/third_party/freetype/src/psaux/psauxerr.h
+++ b/third_party/freetype/src/psaux/psauxerr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PS auxiliary module error codes (specification only).                */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -23,12 +23,12 @@
   /*                                                                       */
   /*************************************************************************/
 
-#ifndef __PSAUXERR_H__
-#define __PSAUXERR_H__
+#ifndef PSAUXERR_H_
+#define PSAUXERR_H_
 
 #include FT_MODULE_ERRORS_H
 
-#undef __FTERRORS_H__
+#undef FTERRORS_H_
 
 #undef  FT_ERR_PREFIX
 #define FT_ERR_PREFIX  PSaux_Err_
@@ -36,7 +36,7 @@
 
 #include FT_ERRORS_H
 
-#endif /* __PSAUXERR_H__ */
+#endif /* PSAUXERR_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/psaux/psauxmod.c b/third_party/freetype/src/psaux/psauxmod.c
index 06fcab0..1f589ce 100644
--- a/third_party/freetype/src/psaux/psauxmod.c
+++ b/third_party/freetype/src/psaux/psauxmod.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType auxiliary PostScript module implementation (body).          */
 /*                                                                         */
-/*  Copyright 2000-2015 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,       */
@@ -30,52 +30,56 @@
   FT_CALLBACK_TABLE_DEF
   const PS_Table_FuncsRec  ps_table_funcs =
   {
-    ps_table_new,
-    ps_table_done,
-    ps_table_add,
-    ps_table_release
+    ps_table_new,     /* init    */
+    ps_table_done,    /* done    */
+    ps_table_add,     /* add     */
+    ps_table_release  /* release */
   };
 
 
   FT_CALLBACK_TABLE_DEF
   const PS_Parser_FuncsRec  ps_parser_funcs =
   {
-    ps_parser_init,
-    ps_parser_done,
-    ps_parser_skip_spaces,
-    ps_parser_skip_PS_token,
-    ps_parser_to_int,
-    ps_parser_to_fixed,
-    ps_parser_to_bytes,
-    ps_parser_to_coord_array,
-    ps_parser_to_fixed_array,
-    ps_parser_to_token,
-    ps_parser_to_token_array,
-    ps_parser_load_field,
-    ps_parser_load_field_table
+    ps_parser_init,             /* init             */
+    ps_parser_done,             /* done             */
+
+    ps_parser_skip_spaces,      /* skip_spaces      */
+    ps_parser_skip_PS_token,    /* skip_PS_token    */
+
+    ps_parser_to_int,           /* to_int           */
+    ps_parser_to_fixed,         /* to_fixed         */
+    ps_parser_to_bytes,         /* to_bytes         */
+    ps_parser_to_coord_array,   /* to_coord_array   */
+    ps_parser_to_fixed_array,   /* to_fixed_array   */
+    ps_parser_to_token,         /* to_token         */
+    ps_parser_to_token_array,   /* to_token_array   */
+
+    ps_parser_load_field,       /* load_field       */
+    ps_parser_load_field_table  /* load_field_table */
   };
 
 
   FT_CALLBACK_TABLE_DEF
   const T1_Builder_FuncsRec  t1_builder_funcs =
   {
-    t1_builder_init,
-    t1_builder_done,
-    t1_builder_check_points,
-    t1_builder_add_point,
-    t1_builder_add_point1,
-    t1_builder_add_contour,
-    t1_builder_start_point,
-    t1_builder_close_contour
+    t1_builder_init,          /* init */
+    t1_builder_done,          /* done */
+
+    t1_builder_check_points,  /* check_points  */
+    t1_builder_add_point,     /* add_point     */
+    t1_builder_add_point1,    /* add_point1    */
+    t1_builder_add_contour,   /* add_contour   */
+    t1_builder_start_point,   /* start_point   */
+    t1_builder_close_contour  /* close_contour */
   };
 
 
   FT_CALLBACK_TABLE_DEF
   const T1_Decoder_FuncsRec  t1_decoder_funcs =
   {
-    t1_decoder_init,
-    t1_decoder_done,
-    t1_decoder_parse_charstrings
+    t1_decoder_init,              /* init              */
+    t1_decoder_done,              /* done              */
+    t1_decoder_parse_charstrings  /* parse_charstrings */
   };
 
 
@@ -83,9 +87,9 @@
   FT_CALLBACK_TABLE_DEF
   const AFM_Parser_FuncsRec  afm_parser_funcs =
   {
-    afm_parser_init,
-    afm_parser_done,
-    afm_parser_parse
+    afm_parser_init,  /* init  */
+    afm_parser_done,  /* done  */
+    afm_parser_parse  /* parse */
   };
 #endif
 
@@ -130,9 +134,9 @@
 
     &psaux_interface,  /* module-specific interface */
 
-    (FT_Module_Constructor)0,
-    (FT_Module_Destructor) 0,
-    (FT_Module_Requester)  0
+    (FT_Module_Constructor)NULL,  /* module_init   */
+    (FT_Module_Destructor) NULL,  /* module_done   */
+    (FT_Module_Requester)  NULL   /* get_interface */
   };
 
 
diff --git a/third_party/freetype/src/psaux/psauxmod.h b/third_party/freetype/src/psaux/psauxmod.h
index ae6a8f9..926f37e 100644
--- a/third_party/freetype/src/psaux/psauxmod.h
+++ b/third_party/freetype/src/psaux/psauxmod.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType auxiliary PostScript module implementation (specification). */
 /*                                                                         */
-/*  Copyright 2000-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __PSAUXMOD_H__
-#define __PSAUXMOD_H__
+#ifndef PSAUXMOD_H_
+#define PSAUXMOD_H_
 
 
 #include <ft2build.h>
@@ -36,7 +36,7 @@
 
 FT_END_HEADER
 
-#endif /* __PSAUXMOD_H__ */
+#endif /* PSAUXMOD_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/psaux/psconv.c b/third_party/freetype/src/psaux/psconv.c
index aca7412..b092482 100644
--- a/third_party/freetype/src/psaux/psconv.c
+++ b/third_party/freetype/src/psaux/psconv.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Some convenience conversions (body).                                 */
 /*                                                                         */
-/*  Copyright 2006-2015 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/third_party/freetype/src/psaux/psconv.h b/third_party/freetype/src/psaux/psconv.h
index 10f1ff7..cab254a 100644
--- a/third_party/freetype/src/psaux/psconv.h
+++ b/third_party/freetype/src/psaux/psconv.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Some convenience conversions (specification).                        */
 /*                                                                         */
-/*  Copyright 2006-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __PSCONV_H__
-#define __PSCONV_H__
+#ifndef PSCONV_H_
+#define PSCONV_H_
 
 
 #include <ft2build.h>
@@ -65,7 +65,7 @@
 
 FT_END_HEADER
 
-#endif /* __PSCONV_H__ */
+#endif /* PSCONV_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/psaux/psobjs.c b/third_party/freetype/src/psaux/psobjs.c
index 1d3c7e6..d18e821 100644
--- a/third_party/freetype/src/psaux/psobjs.c
+++ b/third_party/freetype/src/psaux/psobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auxiliary functions for PostScript fonts (body).                     */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -344,7 +344,7 @@
       FT_Byte  c = *cur;
 
 
-      ++cur;
+      cur++;
 
       if ( c == '\\' )
       {
@@ -370,17 +370,17 @@
         case '\\':
         case '(':
         case ')':
-          ++cur;
+          cur++;
           break;
 
         default:
           /* skip octal escape or ignore backslash */
-          for ( i = 0; i < 3 && cur < limit; ++i )
+          for ( i = 0; i < 3 && cur < limit; i++ )
           {
             if ( !IS_OCTAL_DIGIT( *cur ) )
               break;
 
-            ++cur;
+            cur++;
           }
         }
       }
@@ -455,19 +455,19 @@
 
     FT_ASSERT( **acur == '{' );
 
-    for ( cur = *acur; cur < limit && error == FT_Err_Ok; ++cur )
+    for ( cur = *acur; cur < limit && error == FT_Err_Ok; cur++ )
     {
       switch ( *cur )
       {
       case '{':
-        ++embed;
+        embed++;
         break;
 
       case '}':
-        --embed;
+        embed--;
         if ( embed == 0 )
         {
-          ++cur;
+          cur++;
           goto end;
         }
         break;
@@ -695,7 +695,7 @@
       /* ************ otherwise, it is any token **************/
     default:
       token->start = cur;
-      token->type  = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY );
+      token->type  = ( *cur == '/' ) ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY;
       ps_parser_skip_PS_token( parser );
       cur = parser->cursor;
       if ( !parser->error )
@@ -750,7 +750,7 @@
         if ( !token.type )
           break;
 
-        if ( tokens != NULL && cur < limit )
+        if ( tokens && cur < limit )
           *cur = token;
 
         cur++;
@@ -815,12 +815,12 @@
 
       old_cur = cur;
 
-      if ( coords != NULL && count >= max_coords )
+      if ( coords && count >= max_coords )
         break;
 
       /* call PS_Conv_ToFixed() even if coords == NULL */
       /* to properly parse number at `cur'             */
-      *( coords != NULL ? &coords[count] : &dummy ) =
+      *( coords ? &coords[count] : &dummy ) =
         (FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 );
 
       if ( old_cur == cur )
@@ -895,12 +895,12 @@
 
       old_cur = cur;
 
-      if ( values != NULL && count >= max_values )
+      if ( values && count >= max_values )
         break;
 
       /* call PS_Conv_ToFixed() even if coords == NULL */
       /* to properly parse number at `cur'             */
-      *( values != NULL ? &values[count] : &dummy ) =
+      *( values ? &values[count] : &dummy ) =
         PS_Conv_ToFixed( &cur, limit, power_ten );
 
       if ( old_cur == cur )
@@ -1087,9 +1087,9 @@
 
     for ( ; count > 0; count--, idx++ )
     {
-      FT_Byte*    q = (FT_Byte*)objects[idx] + field->offset;
+      FT_Byte*    q      = (FT_Byte*)objects[idx] + field->offset;
       FT_Long     val;
-      FT_String*  string;
+      FT_String*  string = NULL;
 
 
       skip_spaces( &cur, limit );
@@ -1172,7 +1172,7 @@
 
           /* for this to work (FT_String**)q must have been */
           /* initialized to NULL                            */
-          if ( *(FT_String**)q != NULL )
+          if ( *(FT_String**)q )
           {
             FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n",
                         field->ident ));
@@ -1217,7 +1217,7 @@
       case T1_FIELD_TYPE_MM_BBOX:
         {
           FT_Memory  memory = parser->memory;
-          FT_Fixed*  temp;
+          FT_Fixed*  temp   = NULL;
           FT_Int     result;
           FT_UInt    i;
 
diff --git a/third_party/freetype/src/psaux/psobjs.h b/third_party/freetype/src/psaux/psobjs.h
index bf879c1..202e5b2 100644
--- a/third_party/freetype/src/psaux/psobjs.h
+++ b/third_party/freetype/src/psaux/psobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auxiliary functions for PostScript fonts (specification).            */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __PSOBJS_H__
-#define __PSOBJS_H__
+#ifndef PSOBJS_H_
+#define PSOBJS_H_
 
 
 #include <ft2build.h>
@@ -206,7 +206,7 @@
 
 FT_END_HEADER
 
-#endif /* __PSOBJS_H__ */
+#endif /* PSOBJS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/psaux/t1cmap.c b/third_party/freetype/src/psaux/t1cmap.c
index 2e2d433..45b713e 100644
--- a/third_party/freetype/src/psaux/t1cmap.c
+++ b/third_party/freetype/src/psaux/t1cmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 character map support (body).                                 */
 /*                                                                         */
-/*  Copyright 2002-2015 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,       */
@@ -45,7 +45,7 @@
     cmap->code_to_sid   = is_expert ? psnames->adobe_expert_encoding
                                     : psnames->adobe_std_encoding;
 
-    FT_ASSERT( cmap->code_to_sid != NULL );
+    FT_ASSERT( cmap->code_to_sid );
   }
 
 
@@ -136,12 +136,16 @@
   {
     sizeof ( T1_CMapStdRec ),
 
-    (FT_CMap_InitFunc)     t1_cmap_standard_init,
-    (FT_CMap_DoneFunc)     t1_cmap_std_done,
-    (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,
-    (FT_CMap_CharNextFunc) t1_cmap_std_char_next,
+    (FT_CMap_InitFunc)     t1_cmap_standard_init,   /* init       */
+    (FT_CMap_DoneFunc)     t1_cmap_std_done,        /* done       */
+    (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,  /* char_index */
+    (FT_CMap_CharNextFunc) t1_cmap_std_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 */
   };
 
 
@@ -161,12 +165,16 @@
   {
     sizeof ( T1_CMapStdRec ),
 
-    (FT_CMap_InitFunc)     t1_cmap_expert_init,
-    (FT_CMap_DoneFunc)     t1_cmap_std_done,
-    (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,
-    (FT_CMap_CharNextFunc) t1_cmap_std_char_next,
+    (FT_CMap_InitFunc)     t1_cmap_expert_init,     /* init       */
+    (FT_CMap_DoneFunc)     t1_cmap_std_done,        /* done       */
+    (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,  /* char_index */
+    (FT_CMap_CharNextFunc) t1_cmap_std_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 */
   };
 
 
@@ -193,7 +201,7 @@
     cmap->count   = (FT_UInt)encoding->code_last - cmap->first;
     cmap->indices = encoding->char_index;
 
-    FT_ASSERT( cmap->indices != NULL );
+    FT_ASSERT( cmap->indices );
     FT_ASSERT( encoding->code_first <= encoding->code_last );
 
     return 0;
@@ -232,7 +240,7 @@
     FT_UInt32  char_code = *pchar_code;
 
 
-    ++char_code;
+    char_code++;
 
     if ( char_code < cmap->first )
       char_code = cmap->first;
@@ -257,12 +265,16 @@
   {
     sizeof ( T1_CMapCustomRec ),
 
-    (FT_CMap_InitFunc)     t1_cmap_custom_init,
-    (FT_CMap_DoneFunc)     t1_cmap_custom_done,
-    (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index,
-    (FT_CMap_CharNextFunc) t1_cmap_custom_char_next,
+    (FT_CMap_InitFunc)     t1_cmap_custom_init,        /* init       */
+    (FT_CMap_DoneFunc)     t1_cmap_custom_done,        /* done       */
+    (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index,  /* char_index */
+    (FT_CMap_CharNextFunc) t1_cmap_custom_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 */
   };
 
 
@@ -343,12 +355,16 @@
   {
     sizeof ( PS_UnicodesRec ),
 
-    (FT_CMap_InitFunc)     t1_cmap_unicode_init,
-    (FT_CMap_DoneFunc)     t1_cmap_unicode_done,
-    (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index,
-    (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next,
+    (FT_CMap_InitFunc)     t1_cmap_unicode_init,        /* init       */
+    (FT_CMap_DoneFunc)     t1_cmap_unicode_done,        /* done       */
+    (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index,  /* char_index */
+    (FT_CMap_CharNextFunc) t1_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 */
   };
 
 
diff --git a/third_party/freetype/src/psaux/t1cmap.h b/third_party/freetype/src/psaux/t1cmap.h
index b8ba06c..7870245 100644
--- a/third_party/freetype/src/psaux/t1cmap.h
+++ b/third_party/freetype/src/psaux/t1cmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 character map support (specification).                        */
 /*                                                                         */
-/*  Copyright 2002-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __T1CMAP_H__
-#define __T1CMAP_H__
+#ifndef T1CMAP_H_
+#define T1CMAP_H_
 
 #include <ft2build.h>
 #include FT_INTERNAL_OBJECTS_H
@@ -99,7 +99,7 @@
 
 FT_END_HEADER
 
-#endif /* __T1CMAP_H__ */
+#endif /* T1CMAP_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/psaux/t1decode.c b/third_party/freetype/src/psaux/t1decode.c
index 2e19928..af7b465 100644
--- a/third_party/freetype/src/psaux/t1decode.c
+++ b/third_party/freetype/src/psaux/t1decode.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript Type 1 decoding routines (body).                          */
 /*                                                                         */
-/*  Copyright 2000-2015 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,       */
@@ -20,6 +20,7 @@
 #include FT_INTERNAL_CALC_H
 #include FT_INTERNAL_DEBUG_H
 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
+#include FT_INTERNAL_HASH_H
 #include FT_OUTLINE_H
 
 #include "t1decode.h"
@@ -404,9 +405,7 @@
                ( decoder->buildchar == NULL )  );
 
     if ( decoder->buildchar && decoder->len_buildchar > 0 )
-      ft_memset( &decoder->buildchar[0],
-                 0,
-                 sizeof ( decoder->buildchar[0] ) * decoder->len_buildchar );
+      FT_ARRAY_ZERO( decoder->buildchar, decoder->len_buildchar );
 
     FT_TRACE4(( "\n"
                 "Start charstring\n" ));
@@ -512,7 +511,7 @@
         break;
 
       case 12:
-        if ( ip > limit )
+        if ( ip >= limit )
         {
           FT_ERROR(( "t1_decoder_parse_charstrings:"
                      " invalid escape (12+EOF)\n" ));
@@ -667,9 +666,9 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
         if ( large_int )
-          FT_TRACE4(( " %ld", value ));
+          FT_TRACE4(( " %d", value ));
         else
-          FT_TRACE4(( " %ld", Fix2Int( value ) ));
+          FT_TRACE4(( " %d", value / 65536 ));
 #endif
 
         *top++       = value;
@@ -735,7 +734,7 @@
           if ( arg_cnt != 3 )
             goto Unexpected_OtherSubr;
 
-          if ( decoder->flex_state       == 0 ||
+          if ( !decoder->flex_state           ||
                decoder->num_flex_vectors != 7 )
           {
             FT_ERROR(( "t1_decoder_parse_charstrings:"
@@ -753,13 +752,12 @@
           if ( arg_cnt != 0 )
             goto Unexpected_OtherSubr;
 
+          if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
+               FT_SET_ERROR( t1_builder_check_points( builder, 6 ) )   )
+            goto Fail;
+
           decoder->flex_state        = 1;
           decoder->num_flex_vectors  = 0;
-          if ( ( error = t1_builder_start_point( builder, x, y ) )
-                 != FT_Err_Ok                                   ||
-               ( error = t1_builder_check_points( builder, 6 ) )
-                 != FT_Err_Ok                                   )
-            goto Fail;
           break;
 
         case 2:                     /* add flex vectors */
@@ -770,7 +768,7 @@
             if ( arg_cnt != 0 )
               goto Unexpected_OtherSubr;
 
-            if ( decoder->flex_state == 0 )
+            if ( !decoder->flex_state )
             {
               FT_ERROR(( "t1_decoder_parse_charstrings:"
                          " missing flex start\n" ));
@@ -875,7 +873,7 @@
             PS_Blend  blend = decoder->blend;
 
 
-            if ( arg_cnt != 1 || blend == NULL )
+            if ( arg_cnt != 1 || !blend )
               goto Unexpected_OtherSubr;
 
             idx = Fix2Int( top[0] );
@@ -943,7 +941,7 @@
             PS_Blend  blend = decoder->blend;
 
 
-            if ( arg_cnt != 2 || blend == NULL )
+            if ( arg_cnt != 2 || !blend )
               goto Unexpected_OtherSubr;
 
             idx = Fix2Int( top[1] );
@@ -964,7 +962,7 @@
             PS_Blend  blend = decoder->blend;
 
 
-            if ( arg_cnt != 1 || blend == NULL )
+            if ( arg_cnt != 1 || !blend )
               goto Unexpected_OtherSubr;
 
             idx = Fix2Int( top[0] );
@@ -1122,7 +1120,7 @@
 
             FT_TRACE4(( "BuildCharArray = [ " ));
 
-            for ( i = 0; i < decoder->len_buildchar; ++i )
+            for ( i = 0; i < decoder->len_buildchar; i++ )
               FT_TRACE4(( "%d ", decoder->buildchar[i] ));
 
             FT_TRACE4(( "]\n" ));
@@ -1200,8 +1198,7 @@
         case op_hlineto:
           FT_TRACE4(( " hlineto" ));
 
-          if ( ( error = t1_builder_start_point( builder, x, y ) )
-                 != FT_Err_Ok )
+          if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
             goto Fail;
 
           x += top[0];
@@ -1222,10 +1219,8 @@
         case op_hvcurveto:
           FT_TRACE4(( " hvcurveto" ));
 
-          if ( ( error = t1_builder_start_point( builder, x, y ) )
-                 != FT_Err_Ok                                   ||
-               ( error = t1_builder_check_points( builder, 3 ) )
-                 != FT_Err_Ok                                   )
+          if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
+               FT_SET_ERROR( t1_builder_check_points( builder, 3 ) )   )
             goto Fail;
 
           x += top[0];
@@ -1240,16 +1235,14 @@
         case op_rlineto:
           FT_TRACE4(( " rlineto" ));
 
-          if ( ( error = t1_builder_start_point( builder, x, y ) )
-                 != FT_Err_Ok )
+          if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
             goto Fail;
 
           x += top[0];
           y += top[1];
 
         Add_Line:
-          if ( ( error = t1_builder_add_point1( builder, x, y ) )
-                 != FT_Err_Ok )
+          if ( FT_SET_ERROR( t1_builder_add_point1( builder, x, y ) ) )
             goto Fail;
           break;
 
@@ -1269,10 +1262,8 @@
         case op_rrcurveto:
           FT_TRACE4(( " rrcurveto" ));
 
-          if ( ( error = t1_builder_start_point( builder, x, y ) )
-                 != FT_Err_Ok                                   ||
-               ( error = t1_builder_check_points( builder, 3 ) )
-                 != FT_Err_Ok                                   )
+          if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
+               FT_SET_ERROR( t1_builder_check_points( builder, 3 ) )   )
             goto Fail;
 
           x += top[0];
@@ -1291,10 +1282,8 @@
         case op_vhcurveto:
           FT_TRACE4(( " vhcurveto" ));
 
-          if ( ( error = t1_builder_start_point( builder, x, y ) )
-                 != FT_Err_Ok                                   ||
-               ( error = t1_builder_check_points( builder, 3 ) )
-                 != FT_Err_Ok                                   )
+          if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ||
+               FT_SET_ERROR( t1_builder_check_points( builder, 3 ) )   )
             goto Fail;
 
           y += top[0];
@@ -1309,8 +1298,7 @@
         case op_vlineto:
           FT_TRACE4(( " vlineto" ));
 
-          if ( ( error = t1_builder_start_point( builder, x, y ) )
-                 != FT_Err_Ok )
+          if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
             goto Fail;
 
           y += top[0];
@@ -1335,7 +1323,7 @@
           /* otherwise, we divide numbers in 16.16 format --    */
           /* in both cases, it is the same operation            */
           *top = FT_DivFix( top[0], top[1] );
-          ++top;
+          top++;
 
           large_int = FALSE;
           break;
@@ -1348,6 +1336,19 @@
             FT_TRACE4(( " callsubr" ));
 
             idx = Fix2Int( top[0] );
+
+            if ( decoder->subrs_hash )
+            {
+              size_t*  val = ft_hash_num_lookup( idx,
+                                                 decoder->subrs_hash );
+
+
+              if ( val )
+                idx = *val;
+              else
+                idx = -1;
+            }
+
             if ( idx < 0 || idx >= decoder->num_subrs )
             {
               FT_ERROR(( "t1_decoder_parse_charstrings:"
@@ -1577,7 +1578,7 @@
                    FT_Render_Mode       hint_mode,
                    T1_Decoder_Callback  parse_callback )
   {
-    FT_MEM_ZERO( decoder, sizeof ( *decoder ) );
+    FT_ZERO( decoder );
 
     /* retrieve PSNames interface from list of current modules */
     {
diff --git a/third_party/freetype/src/psaux/t1decode.h b/third_party/freetype/src/psaux/t1decode.h
index e83078f..12c27de 100644
--- a/third_party/freetype/src/psaux/t1decode.h
+++ b/third_party/freetype/src/psaux/t1decode.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript Type 1 decoding routines (specification).                 */
 /*                                                                         */
-/*  Copyright 2000-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __T1DECODE_H__
-#define __T1DECODE_H__
+#ifndef T1DECODE_H_
+#define T1DECODE_H_
 
 
 #include <ft2build.h>
@@ -58,7 +58,7 @@
 
 FT_END_HEADER
 
-#endif /* __T1DECODE_H__ */
+#endif /* T1DECODE_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/pshinter/pshalgo.c b/third_party/freetype/src/pshinter/pshalgo.c
index 6e654cb..9ad1a3a 100644
--- a/third_party/freetype/src/pshinter/pshalgo.c
+++ b/third_party/freetype/src/pshinter/pshalgo.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript hinting algorithm (body).                                 */
 /*                                                                         */
-/*  Copyright 2001-2015 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        */
@@ -779,7 +779,7 @@
            * It turns out though that minimizing the total number of lit
            * pixels is also important, so position C), with one edge
            * aligned with a pixel boundary is actually preferable
-           * to A).  There are also more possibile positions for C) than
+           * to A).  There are also more possible positions for C) than
            * for A) or B), so it involves less distortion of the overall
            * character shape.
            */
@@ -802,7 +802,7 @@
             }
 
             /* We choose between B) and C) above based on the amount
-             * of fractinal stem width; for small amounts, choose
+             * of fractional stem width; for small amounts, choose
              * C) always, for large amounts, B) always, and inbetween,
              * pick whichever one involves less stem movement.
              */
@@ -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/third_party/freetype/src/pshinter/pshalgo.h b/third_party/freetype/src/pshinter/pshalgo.h
index 8373e5e..62e97d1 100644
--- a/third_party/freetype/src/pshinter/pshalgo.h
+++ b/third_party/freetype/src/pshinter/pshalgo.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript hinting algorithm (specification).                        */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __PSHALGO_H__
-#define __PSHALGO_H__
+#ifndef PSHALGO_H_
+#define PSHALGO_H_
 
 
 #include "pshrec.h"
@@ -235,7 +235,7 @@
 FT_END_HEADER
 
 
-#endif /* __PSHALGO_H__ */
+#endif /* PSHALGO_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/pshinter/pshglob.c b/third_party/freetype/src/pshinter/pshglob.c
index 4616bdc..c68770c 100644
--- a/third_party/freetype/src/pshinter/pshglob.c
+++ b/third_party/freetype/src/pshinter/pshglob.c
@@ -5,7 +5,7 @@
 /*    PostScript hinter global hinting management (body).                  */
 /*    Inspired by the new auto-hinter module.                              */
 /*                                                                         */
-/*  Copyright 2001-2015 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        */
@@ -80,7 +80,7 @@
 
 #if 0
 
-  /* org_width is is font units, result in device pixels, 26.6 format */
+  /* org_width is in font units, result in device pixels, 26.6 format */
   FT_LOCAL_DEF( FT_Pos )
   psh_dimension_snap_width( PSH_Dimension  dimension,
                             FT_Int         org_width )
diff --git a/third_party/freetype/src/pshinter/pshglob.h b/third_party/freetype/src/pshinter/pshglob.h
index c376df7..8801cba 100644
--- a/third_party/freetype/src/pshinter/pshglob.h
+++ b/third_party/freetype/src/pshinter/pshglob.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript hinter global hinting management.                         */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __PSHGLOB_H__
-#define __PSHGLOB_H__
+#ifndef PSHGLOB_H_
+#define PSHGLOB_H_
 
 
 #include FT_FREETYPE_H
@@ -190,7 +190,7 @@
 FT_END_HEADER
 
 
-#endif /* __PSHGLOB_H__ */
+#endif /* PSHGLOB_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/pshinter/pshinter.c b/third_party/freetype/src/pshinter/pshinter.c
index 9e65fe2..e6727ae 100644
--- a/third_party/freetype/src/pshinter/pshinter.c
+++ b/third_party/freetype/src/pshinter/pshinter.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType PostScript Hinting module                                   */
 /*                                                                         */
-/*  Copyright 2001-2015 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/third_party/freetype/src/pshinter/pshmod.c b/third_party/freetype/src/pshinter/pshmod.c
index 961b468..860dc0a 100644
--- a/third_party/freetype/src/pshinter/pshmod.c
+++ b/third_party/freetype/src/pshinter/pshmod.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType PostScript hinter module implementation (body).             */
 /*                                                                         */
-/*  Copyright 2001-2015 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/third_party/freetype/src/pshinter/pshmod.h b/third_party/freetype/src/pshinter/pshmod.h
index a58d856..1d2b40f 100644
--- a/third_party/freetype/src/pshinter/pshmod.h
+++ b/third_party/freetype/src/pshinter/pshmod.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript hinter module interface (specification).                  */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __PSHMOD_H__
-#define __PSHMOD_H__
+#ifndef PSHMOD_H_
+#define PSHMOD_H_
 
 
 #include <ft2build.h>
@@ -33,7 +33,7 @@
 FT_END_HEADER
 
 
-#endif /* __PSHMOD_H__ */
+#endif /* PSHMOD_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/pshinter/pshnterr.h b/third_party/freetype/src/pshinter/pshnterr.h
index ce790a8..73d144e 100644
--- a/third_party/freetype/src/pshinter/pshnterr.h
+++ b/third_party/freetype/src/pshinter/pshnterr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PS Hinter error codes (specification only).                          */
 /*                                                                         */
-/*  Copyright 2003-2015 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,       */
@@ -22,12 +22,12 @@
   /*                                                                       */
   /*************************************************************************/
 
-#ifndef __PSHNTERR_H__
-#define __PSHNTERR_H__
+#ifndef PSHNTERR_H_
+#define PSHNTERR_H_
 
 #include FT_MODULE_ERRORS_H
 
-#undef __FTERRORS_H__
+#undef FTERRORS_H_
 
 #undef  FT_ERR_PREFIX
 #define FT_ERR_PREFIX  PSH_Err_
@@ -35,7 +35,7 @@
 
 #include FT_ERRORS_H
 
-#endif /* __PSHNTERR_H__ */
+#endif /* PSHNTERR_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/pshinter/pshpic.c b/third_party/freetype/src/pshinter/pshpic.c
index afd8fb9..c0d3a64 100644
--- a/third_party/freetype/src/pshinter/pshpic.c
+++ b/third_party/freetype/src/pshinter/pshpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for pshinter module. */
 /*                                                                         */
-/*  Copyright 2009-2015 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/third_party/freetype/src/pshinter/pshpic.h b/third_party/freetype/src/pshinter/pshpic.h
index ca35cd6..8d9a01c 100644
--- a/third_party/freetype/src/pshinter/pshpic.h
+++ b/third_party/freetype/src/pshinter/pshpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for pshinter module. */
 /*                                                                         */
-/*  Copyright 2009-2015 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __PSHPIC_H__
-#define __PSHPIC_H__
+#ifndef PSHPIC_H_
+#define PSHPIC_H_
 
 
 #include FT_INTERNAL_PIC_H
@@ -57,7 +57,7 @@
 
  /* */
 
-#endif /* __PSHPIC_H__ */
+#endif /* PSHPIC_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/pshinter/pshrec.c b/third_party/freetype/src/pshinter/pshrec.c
index f8895fc..fff6d34 100644
--- a/third_party/freetype/src/pshinter/pshrec.c
+++ b/third_party/freetype/src/pshinter/pshrec.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType PostScript hints recorder (body).                           */
 /*                                                                         */
-/*  Copyright 2001-2015 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/third_party/freetype/src/pshinter/pshrec.h b/third_party/freetype/src/pshinter/pshrec.h
index 2b1ad94..e10bc2b 100644
--- a/third_party/freetype/src/pshinter/pshrec.h
+++ b/third_party/freetype/src/pshinter/pshrec.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Postscript (Type1/Type2) hints recorder (specification).             */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -28,8 +28,8 @@
   /**************************************************************************/
 
 
-#ifndef __PSHREC_H__
-#define __PSHREC_H__
+#ifndef PSHREC_H_
+#define PSHREC_H_
 
 
 #include <ft2build.h>
@@ -166,7 +166,7 @@
 FT_END_HEADER
 
 
-#endif /* __PS_HINTER_RECORD_H__ */
+#endif /* PSHREC_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/psnames/psmodule.c b/third_party/freetype/src/psnames/psmodule.c
index 0f04c2f..3ff8cb9 100644
--- a/third_party/freetype/src/psnames/psmodule.c
+++ b/third_party/freetype/src/psnames/psmodule.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PSNames module implementation (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2015 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,37 +528,42 @@
 
   FT_DEFINE_SERVICE_PSCMAPSREC(
     pscmaps_interface,
-    (PS_Unicode_ValueFunc)     ps_unicode_value,
-    (PS_Unicodes_InitFunc)     ps_unicodes_init,
-    (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index,
-    (PS_Unicodes_CharNextFunc) ps_unicodes_char_next,
 
-    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,
-    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
+    (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   */
+    (PS_Unicodes_CharNextFunc) ps_unicodes_char_next,   /* unicodes_char_next    */
 
-    t1_standard_encoding,
-    t1_expert_encoding )
+    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,   /* macintosh_name        */
+    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings     */
+
+    t1_standard_encoding,                               /* adobe_std_encoding    */
+    t1_expert_encoding                                  /* adobe_expert_encoding */
+  )
 
 #else
 
   FT_DEFINE_SERVICE_PSCMAPSREC(
     pscmaps_interface,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
 
-    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,
-    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
+    NULL,                                               /* unicode_value         */
+    NULL,                                               /* unicodes_init         */
+    NULL,                                               /* unicodes_char_index   */
+    NULL,                                               /* unicodes_char_next    */
 
-    t1_standard_encoding,
-    t1_expert_encoding )
+    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,   /* macintosh_name        */
+    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings     */
+
+    t1_standard_encoding,                               /* adobe_std_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/third_party/freetype/src/psnames/psmodule.h b/third_party/freetype/src/psnames/psmodule.h
index f85f322..6983b79 100644
--- a/third_party/freetype/src/psnames/psmodule.h
+++ b/third_party/freetype/src/psnames/psmodule.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level PSNames module interface (specification).                 */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __PSMODULE_H__
-#define __PSMODULE_H__
+#ifndef PSMODULE_H_
+#define PSMODULE_H_
 
 
 #include <ft2build.h>
@@ -32,7 +32,7 @@
 
 FT_END_HEADER
 
-#endif /* __PSMODULE_H__ */
+#endif /* PSMODULE_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/psnames/psnamerr.h b/third_party/freetype/src/psnames/psnamerr.h
index 09cc247..f90bf5e 100644
--- a/third_party/freetype/src/psnames/psnamerr.h
+++ b/third_party/freetype/src/psnames/psnamerr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PS names module error codes (specification only).                    */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -23,12 +23,12 @@
   /*                                                                       */
   /*************************************************************************/
 
-#ifndef __PSNAMERR_H__
-#define __PSNAMERR_H__
+#ifndef PSNAMERR_H_
+#define PSNAMERR_H_
 
 #include FT_MODULE_ERRORS_H
 
-#undef __FTERRORS_H__
+#undef FTERRORS_H_
 
 #undef  FT_ERR_PREFIX
 #define FT_ERR_PREFIX  PSnames_Err_
@@ -36,7 +36,7 @@
 
 #include FT_ERRORS_H
 
-#endif /* __PSNAMERR_H__ */
+#endif /* PSNAMERR_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/psnames/pspic.c b/third_party/freetype/src/psnames/pspic.c
index 1394f97..8b90034 100644
--- a/third_party/freetype/src/psnames/pspic.c
+++ b/third_party/freetype/src/psnames/pspic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for psnames module.  */
 /*                                                                         */
-/*  Copyright 2009-2015 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/third_party/freetype/src/psnames/pspic.h b/third_party/freetype/src/psnames/pspic.h
index 443225a..14497e7 100644
--- a/third_party/freetype/src/psnames/pspic.h
+++ b/third_party/freetype/src/psnames/pspic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for psnames module.  */
 /*                                                                         */
-/*  Copyright 2009-2015 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __PSPIC_H__
-#define __PSPIC_H__
+#ifndef PSPIC_H_
+#define PSPIC_H_
 
 
 #include FT_INTERNAL_PIC_H
@@ -62,7 +62,7 @@
 
  /* */
 
-#endif /* __PSPIC_H__ */
+#endif /* PSPIC_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/psnames/pstables.h b/third_party/freetype/src/psnames/pstables.h
index 3f31c31..e0f5e30 100644
--- a/third_party/freetype/src/psnames/pstables.h
+++ b/third_party/freetype/src/psnames/pstables.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript glyph names.                                              */
 /*                                                                         */
-/*  Copyright 2005-2015 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/third_party/freetype/src/raster/ftraster.c b/third_party/freetype/src/raster/ftraster.c
index e4bab98..c5643f6 100644
--- a/third_party/freetype/src/raster/ftraster.c
+++ b/third_party/freetype/src/raster/ftraster.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph rasterizer (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -18,7 +18,7 @@
   /*************************************************************************/
   /*                                                                       */
   /* This file can be compiled without the rest of the FreeType engine, by */
-  /* defining the _STANDALONE_ macro when compiling it.  You also need to  */
+  /* defining the STANDALONE_ macro when compiling it.  You also need to   */
   /* put the files `ftimage.h' and `ftmisc.h' into the $(incdir)           */
   /* directory.  Typically, you should do something like                   */
   /*                                                                       */
@@ -27,9 +27,9 @@
   /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' to your */
   /*   current directory                                                   */
   /*                                                                       */
-  /* - compile `ftraster' with the _STANDALONE_ macro defined, as in       */
+  /* - compile `ftraster' with the STANDALONE_ macro defined, as in        */
   /*                                                                       */
-  /*     cc -c -D_STANDALONE_ ftraster.c                                   */
+  /*     cc -c -DSTANDALONE_ ftraster.c                                    */
   /*                                                                       */
   /* The renderer can be initialized with a call to                        */
   /* `ft_standard_raster.raster_new'; a bitmap can be generated            */
@@ -47,7 +47,7 @@
   /*                                                                       */
   /*************************************************************************/
 
-#ifdef _STANDALONE_
+#ifdef STANDALONE_
 
   /* The size in bytes of the render pool used by the scan-line converter  */
   /* to do all of its work.                                                */
@@ -60,7 +60,7 @@
 #include "ftmisc.h"
 #include "ftimage.h"
 
-#else /* !_STANDALONE_ */
+#else /* !STANDALONE_ */
 
 #include <ft2build.h>
 #include "ftraster.h"
@@ -68,7 +68,7 @@
 
 #include "rastpic.h"
 
-#endif /* !_STANDALONE_ */
+#endif /* !STANDALONE_ */
 
 
   /*************************************************************************/
@@ -173,14 +173,12 @@
 #define FT_COMPONENT  trace_raster
 
 
-#ifdef _STANDALONE_
+#ifdef STANDALONE_
 
   /* Auxiliary macros for token concatenation. */
 #define FT_ERR_XCAT( x, y )  x ## y
 #define FT_ERR_CAT( x, y )   FT_ERR_XCAT( x, y )
 
-#define FT_MAX( a, b )  ( (a) > (b) ? (a) : (b) )
-
   /* This macro is used to indicate that a function parameter is unused. */
   /* Its purpose is simply to reduce compiler warnings.  Note also that  */
   /* simply defining it as `(void)x' doesn't avoid warnings with certain */
@@ -226,7 +224,7 @@
             raster_done_                                            \
          };
 
-#else /* !_STANDALONE_ */
+#else /* !STANDALONE_ */
 
 
 #include FT_INTERNAL_OBJECTS_H
@@ -242,7 +240,7 @@
 #define Raster_Err_Unsupported  Raster_Err_Cannot_Render_Glyph
 
 
-#endif /* !_STANDALONE_ */
+#endif /* !STANDALONE_ */
 
 
 #ifndef FT_MEM_SET
@@ -253,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.                                                           */
@@ -459,6 +461,12 @@
 #define IS_TOP_OVERSHOOT( x )    \
           (Bool)( x - FLOOR( x ) >= ras.precision_half )
 
+#if FT_RENDER_POOL_SIZE > 2048
+#define FT_MAX_BLACK_POOL  ( FT_RENDER_POOL_SIZE / sizeof ( Long ) )
+#else
+#define FT_MAX_BLACK_POOL  ( 2048 / sizeof ( Long ) )
+#endif
+
   /* The most used variables are positioned at the top of the structure. */
   /* Thus, their offset can be coded with less opcodes, resulting in a   */
   /* smaller executable.                                                 */
@@ -1512,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 */
@@ -1648,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 */
@@ -2382,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 );
 
@@ -2583,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 );
 
@@ -3041,7 +3051,7 @@
   /****                         a static object.                  *****/
 
 
-#ifdef _STANDALONE_
+#ifdef STANDALONE_
 
 
   static int
@@ -3053,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;
@@ -3068,7 +3078,7 @@
   }
 
 
-#else /* !_STANDALONE_ */
+#else /* !STANDALONE_ */
 
 
   static int
@@ -3102,13 +3112,13 @@
   }
 
 
-#endif /* !_STANDALONE_ */
+#endif /* !STANDALONE_ */
 
 
   static void
-  ft_black_reset( black_PRaster  raster,
-                  char*          pool_base,
-                  Long           pool_size )
+  ft_black_reset( FT_Raster  raster,
+                  PByte      pool_base,
+                  ULong      pool_size )
   {
     FT_UNUSED( raster );
     FT_UNUSED( pool_base );
@@ -3117,20 +3127,20 @@
 
 
   static int
-  ft_black_set_mode( black_PRaster  raster,
-                     ULong          mode,
-                     const char*    palette )
+  ft_black_set_mode( FT_Raster  raster,
+                     ULong      mode,
+                     void*      args )
   {
     FT_UNUSED( raster );
     FT_UNUSED( mode );
-    FT_UNUSED( palette );
+    FT_UNUSED( args );
 
     return 0;
   }
 
 
   static int
-  ft_black_render( black_PRaster            raster,
+  ft_black_render( FT_Raster                raster,
                    const FT_Raster_Params*  params )
   {
     const FT_Outline*  outline    = (const FT_Outline*)params->source;
@@ -3138,7 +3148,7 @@
 
     black_TWorker  worker[1];
 
-    Long  buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( Long )];
+    Long  buffer[FT_MAX_BLACK_POOL];
 
 
     if ( !raster )
@@ -3175,6 +3185,20 @@
     if ( !target_map->buffer )
       return FT_THROW( Invalid );
 
+    /* reject too large outline coordinates */
+    {
+      FT_Vector*  vec   = outline->points;
+      FT_Vector*  limit = vec + outline->n_points;
+
+
+      for ( ; vec < limit; vec++ )
+      {
+        if ( vec->x < -0x1000000L || vec->x > 0x1000000L ||
+             vec->y < -0x1000000L || vec->y > 0x1000000L )
+         return FT_THROW( Invalid );
+      }
+    }
+
     ras.outline = *outline;
     ras.target  = *target_map;
 
@@ -3190,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/third_party/freetype/src/raster/ftraster.h b/third_party/freetype/src/raster/ftraster.h
index a270d48..6b3050c 100644
--- a/third_party/freetype/src/raster/ftraster.h
+++ b/third_party/freetype/src/raster/ftraster.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph rasterizer (specification).                       */
 /*                                                                         */
-/*  Copyright 1996-2015 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        */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTRASTER_H__
-#define __FTRASTER_H__
+#ifndef FTRASTER_H_
+#define FTRASTER_H_
 
 
 #include <ft2build.h>
@@ -33,14 +33,14 @@
   /* Uncomment the following line if you are using ftraster.c as a         */
   /* standalone module, fully independent of FreeType.                     */
   /*                                                                       */
-/* #define _STANDALONE_ */
+/* #define STANDALONE_ */
 
   FT_EXPORT_VAR( const FT_Raster_Funcs )  ft_standard_raster;
 
 
 FT_END_HEADER
 
-#endif /* __FTRASTER_H__ */
+#endif /* FTRASTER_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/raster/ftrend1.c b/third_party/freetype/src/raster/ftrend1.c
index f314392..1a83e9e 100644
--- a/third_party/freetype/src/raster/ftrend1.c
+++ b/third_party/freetype/src/raster/ftrend1.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph rasterizer interface (body).                      */
 /*                                                                         */
-/*  Copyright 1996-2015 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/third_party/freetype/src/raster/ftrend1.h b/third_party/freetype/src/raster/ftrend1.h
index edc5d13..cff702d 100644
--- a/third_party/freetype/src/raster/ftrend1.h
+++ b/third_party/freetype/src/raster/ftrend1.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph rasterizer interface (specification).             */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTREND1_H__
-#define __FTREND1_H__
+#ifndef FTREND1_H_
+#define FTREND1_H_
 
 
 #include <ft2build.h>
@@ -32,7 +32,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTREND1_H__ */
+#endif /* FTREND1_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/raster/raster.c b/third_party/freetype/src/raster/raster.c
index 21bb16d..ee54ae1 100644
--- a/third_party/freetype/src/raster/raster.c
+++ b/third_party/freetype/src/raster/raster.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType monochrome rasterer module component (body only).           */
 /*                                                                         */
-/*  Copyright 1996-2015 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/third_party/freetype/src/raster/rasterrs.h b/third_party/freetype/src/raster/rasterrs.h
index e7f00bc..0d64690 100644
--- a/third_party/freetype/src/raster/rasterrs.h
+++ b/third_party/freetype/src/raster/rasterrs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    monochrome renderer error codes (specification only).                */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -23,12 +23,12 @@
   /*                                                                       */
   /*************************************************************************/
 
-#ifndef __RASTERRS_H__
-#define __RASTERRS_H__
+#ifndef RASTERRS_H_
+#define RASTERRS_H_
 
 #include FT_MODULE_ERRORS_H
 
-#undef __FTERRORS_H__
+#undef FTERRORS_H_
 
 #undef  FT_ERR_PREFIX
 #define FT_ERR_PREFIX  Raster_Err_
@@ -36,7 +36,7 @@
 
 #include FT_ERRORS_H
 
-#endif /* __RASTERRS_H__ */
+#endif /* RASTERRS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/raster/rastpic.c b/third_party/freetype/src/raster/rastpic.c
index 77e7ec3..7085339 100644
--- a/third_party/freetype/src/raster/rastpic.c
+++ b/third_party/freetype/src/raster/rastpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for raster module.   */
 /*                                                                         */
-/*  Copyright 2009-2015 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/third_party/freetype/src/raster/rastpic.h b/third_party/freetype/src/raster/rastpic.h
index 408996a..dcd6913 100644
--- a/third_party/freetype/src/raster/rastpic.h
+++ b/third_party/freetype/src/raster/rastpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for raster module.   */
 /*                                                                         */
-/*  Copyright 2009-2015 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __RASTPIC_H__
-#define __RASTPIC_H__
+#ifndef RASTPIC_H_
+#define RASTPIC_H_
 
 
 #include FT_INTERNAL_PIC_H
@@ -57,7 +57,7 @@
 
 FT_END_HEADER
 
-#endif /* __RASTPIC_H__ */
+#endif /* RASTPIC_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/sfnt/sfdriver.c b/third_party/freetype/src/sfnt/sfdriver.c
index 6a3f0d9..0b9867a 100644
--- a/third_party/freetype/src/sfnt/sfdriver.c
+++ b/third_party/freetype/src/sfnt/sfdriver.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level SFNT driver interface (body).                             */
 /*                                                                         */
-/*  Copyright 1996-2015 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,
-    (FT_SFNT_TableGetFunc) get_sfnt_table,
-    (FT_SFNT_TableInfoFunc)sfnt_table_info )
+
+    (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 */
+  )
 
 
 #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,
-    (FT_GlyphDict_NameIndexFunc)sfnt_get_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 */
 
@@ -330,7 +333,9 @@
 
   FT_DEFINE_SERVICE_PSFONTNAMEREC(
     sfnt_service_ps_name,
-    (FT_PsName_GetFunc)sfnt_get_ps_name )
+
+    (FT_PsName_GetFunc)sfnt_get_ps_name       /* get_ps_font_name */
+  )
 
 
   /*
@@ -338,7 +343,9 @@
    */
   FT_DEFINE_SERVICE_TTCMAPSREC(
     tt_service_get_cmap_info,
-    (TT_CMap_Info_GetFunc)tt_get_cmap_info )
+
+    (TT_CMap_Info_GetFunc)tt_get_cmap_info    /* get_cmap_info */
+  )
 
 
 #ifdef TT_CONFIG_OPTION_BDF
@@ -381,8 +388,10 @@
 
   FT_DEFINE_SERVICE_BDFRec(
     sfnt_service_bdf,
-    (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id,
-    (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop )
+
+    (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id,     /* get_charset_id */
+    (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop    /* get_property   */
+  )
 
 
 #endif /* TT_CONFIG_OPTION_BDF */
@@ -395,6 +404,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 +413,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 +421,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 +429,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,55 +472,63 @@
 
   FT_DEFINE_SFNT_INTERFACE(
     sfnt_interface,
-    tt_face_goto_table,
 
-    sfnt_init_face,
-    sfnt_load_face,
-    sfnt_done_face,
-    sfnt_get_interface,
+    tt_face_goto_table,     /* TT_Loader_GotoTableFunc goto_table      */
 
-    tt_face_load_any,
+    sfnt_init_face,         /* TT_Init_Face_Func       init_face       */
+    sfnt_load_face,         /* TT_Load_Face_Func       load_face       */
+    sfnt_done_face,         /* TT_Done_Face_Func       done_face       */
+    sfnt_get_interface,     /* FT_Module_Requester     get_interface   */
 
-    tt_face_load_head,
-    tt_face_load_hhea,
-    tt_face_load_cmap,
-    tt_face_load_maxp,
-    tt_face_load_os2,
-    tt_face_load_post,
+    tt_face_load_any,       /* TT_Load_Any_Func        load_any        */
 
-    tt_face_load_name,
-    tt_face_free_name,
+    tt_face_load_head,      /* TT_Load_Table_Func      load_head       */
+    tt_face_load_hhea,      /* TT_Load_Metrics_Func    load_hhea       */
+    tt_face_load_cmap,      /* TT_Load_Table_Func      load_cmap       */
+    tt_face_load_maxp,      /* TT_Load_Table_Func      load_maxp       */
+    tt_face_load_os2,       /* TT_Load_Table_Func      load_os2        */
+    tt_face_load_post,      /* TT_Load_Table_Func      load_post       */
 
-    tt_face_load_kern,
-    tt_face_load_gasp,
-    tt_face_load_pclt,
+    tt_face_load_name,      /* TT_Load_Table_Func      load_name       */
+    tt_face_free_name,      /* TT_Free_Table_Func      free_name       */
+
+    tt_face_load_kern,      /* TT_Load_Table_Func      load_kern       */
+    tt_face_load_gasp,      /* TT_Load_Table_Func      load_gasp       */
+    tt_face_load_pclt,      /* TT_Load_Table_Func      load_init       */
 
     /* see `ttload.h' */
     PUT_EMBEDDED_BITMAPS( tt_face_load_bhed ),
-
+                            /* TT_Load_Table_Func      load_bhed       */
     PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image ),
+                            /* TT_Load_SBit_Image_Func load_sbit_image */
 
     /* see `ttpost.h' */
     PUT_PS_NAMES( tt_face_get_ps_name   ),
+                            /* TT_Get_PS_Name_Func     get_psname      */
     PUT_PS_NAMES( tt_face_free_ps_names ),
+                            /* TT_Free_Table_Func      free_psnames    */
 
     /* since version 2.1.8 */
-    tt_face_get_kerning,
+    tt_face_get_kerning,    /* TT_Face_GetKerningFunc  get_kerning     */
 
     /* since version 2.2 */
-    tt_face_load_font_dir,
-    tt_face_load_hmtx,
+    tt_face_load_font_dir,  /* TT_Load_Table_Func      load_font_dir   */
+    tt_face_load_hmtx,      /* TT_Load_Metrics_Func    load_hmtx       */
 
     /* see `ttsbit.h' and `sfnt.h' */
     PUT_EMBEDDED_BITMAPS( tt_face_load_sbit ),
+                            /* TT_Load_Table_Func      load_eblc       */
     PUT_EMBEDDED_BITMAPS( tt_face_free_sbit ),
+                            /* TT_Free_Table_Func      free_eblc       */
 
     PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike     ),
+                            /* TT_Set_SBit_Strike_Func set_sbit_strike */
     PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ),
+                    /* TT_Load_Strike_Metrics_Func load_strike_metrics */
 
-    tt_face_get_metrics,
+    tt_face_get_metrics,    /* TT_Get_Metrics_Func     get_metrics     */
 
-    tt_face_get_name
+    tt_face_get_name        /* TT_Get_Name_Func        get_name        */
   )
 
 
@@ -523,9 +544,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/third_party/freetype/src/sfnt/sfdriver.h b/third_party/freetype/src/sfnt/sfdriver.h
index 944119c..38710b6 100644
--- a/third_party/freetype/src/sfnt/sfdriver.h
+++ b/third_party/freetype/src/sfnt/sfdriver.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level SFNT driver interface (specification).                    */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SFDRIVER_H__
-#define __SFDRIVER_H__
+#ifndef SFDRIVER_H_
+#define SFDRIVER_H_
 
 
 #include <ft2build.h>
@@ -32,7 +32,7 @@
 
 FT_END_HEADER
 
-#endif /* __SFDRIVER_H__ */
+#endif /* SFDRIVER_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/sfnt/sferrors.h b/third_party/freetype/src/sfnt/sferrors.h
index e3bef3f..3cf73d7 100644
--- a/third_party/freetype/src/sfnt/sferrors.h
+++ b/third_party/freetype/src/sfnt/sferrors.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    SFNT error codes (specification only).                               */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -22,12 +22,12 @@
   /*                                                                       */
   /*************************************************************************/
 
-#ifndef __SFERRORS_H__
-#define __SFERRORS_H__
+#ifndef SFERRORS_H_
+#define SFERRORS_H_
 
 #include FT_MODULE_ERRORS_H
 
-#undef __FTERRORS_H__
+#undef FTERRORS_H_
 
 #undef  FT_ERR_PREFIX
 #define FT_ERR_PREFIX  SFNT_Err_
@@ -35,6 +35,7 @@
 
 #include FT_ERRORS_H
 
-#endif /* __SFERRORS_H__ */
+#endif /* SFERRORS_H_ */
+
 
 /* END */
diff --git a/third_party/freetype/src/sfnt/sfnt.c b/third_party/freetype/src/sfnt/sfnt.c
index 0b8b5f4..cffda6e 100644
--- a/third_party/freetype/src/sfnt/sfnt.c
+++ b/third_party/freetype/src/sfnt/sfnt.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Single object library component.                                     */
 /*                                                                         */
-/*  Copyright 1996-2015 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/third_party/freetype/src/sfnt/sfntpic.c b/third_party/freetype/src/sfnt/sfntpic.c
index 2aaf4bc..8eadd60 100644
--- a/third_party/freetype/src/sfnt/sfntpic.c
+++ b/third_party/freetype/src/sfnt/sfntpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for sfnt module.     */
 /*                                                                         */
-/*  Copyright 2009-2015 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/third_party/freetype/src/sfnt/sfntpic.h b/third_party/freetype/src/sfnt/sfntpic.h
index d99be6a..3afb668 100644
--- a/third_party/freetype/src/sfnt/sfntpic.h
+++ b/third_party/freetype/src/sfnt/sfntpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for sfnt module.     */
 /*                                                                         */
-/*  Copyright 2009-2015 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SFNTPIC_H__
-#define __SFNTPIC_H__
+#ifndef SFNTPIC_H_
+#define SFNTPIC_H_
 
 
 #include FT_INTERNAL_PIC_H
@@ -106,7 +106,7 @@
 
   /* */
 
-#endif /* __SFNTPIC_H__ */
+#endif /* SFNTPIC_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/sfnt/sfobjs.c b/third_party/freetype/src/sfnt/sfobjs.c
index 14d3ade..8ac868d 100644
--- a/third_party/freetype/src/sfnt/sfobjs.c
+++ b/third_party/freetype/src/sfnt/sfobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    SFNT object management (base).                                       */
 /*                                                                         */
-/*  Copyright 1996-2015 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
@@ -254,7 +260,7 @@
 
     if ( rec && convert )
     {
-      if ( rec->string == NULL )
+      if ( !rec->string )
       {
         FT_Stream  stream = face->name_table.stream;
 
@@ -451,10 +457,14 @@
                                      woff.metaOrigLength != 0 ) ) ||
          ( woff.metaLength != 0 && woff.metaOrigLength == 0 )     ||
          ( woff.privOffset == 0 && woff.privLength != 0 )         )
+    {
+      FT_ERROR(( "woff_font_open: invalid WOFF header\n" ));
       return FT_THROW( Invalid_Table );
+    }
 
-    if ( FT_ALLOC( sfnt, woff.totalSfntSize ) ||
-         FT_NEW( sfnt_stream )                )
+    /* Don't trust `totalSfntSize' before thorough checks. */
+    if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) ||
+         FT_NEW( sfnt_stream )                         )
       goto Exit;
 
     sfnt_header = sfnt;
@@ -521,6 +531,8 @@
       if ( table->Tag <= old_tag )
       {
         FT_FRAME_EXIT();
+
+        FT_ERROR(( "woff_font_open: table tags are not sorted\n" ));
         error = FT_THROW( Invalid_Table );
         goto Exit;
       }
@@ -555,6 +567,7 @@
            sfnt_offset > woff.totalSfntSize - table->OrigLength ||
            table->CompLength > table->OrigLength                )
       {
+        FT_ERROR(( "woff_font_open: invalid table offsets\n" ));
         error = FT_THROW( Invalid_Table );
         goto Exit;
       }
@@ -580,6 +593,8 @@
       if ( woff.metaOffset != woff_offset                  ||
            woff.metaOffset + woff.metaLength > woff.length )
       {
+        FT_ERROR(( "woff_font_open:"
+                   " invalid `metadata' offset or length\n" ));
         error = FT_THROW( Invalid_Table );
         goto Exit;
       }
@@ -596,6 +611,7 @@
       if ( woff.privOffset != woff_offset                  ||
            woff.privOffset + woff.privLength > woff.length )
       {
+        FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" ));
         error = FT_THROW( Invalid_Table );
         goto Exit;
       }
@@ -607,10 +623,19 @@
     if ( sfnt_offset != woff.totalSfntSize ||
          woff_offset != woff.length        )
     {
+      FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" ));
       error = FT_THROW( Invalid_Table );
       goto Exit;
     }
 
+    /* Now use `totalSfntSize'. */
+    if ( FT_REALLOC( sfnt,
+                     12 + woff.num_tables * 16UL,
+                     woff.totalSfntSize ) )
+      goto Exit;
+
+    sfnt_header = sfnt + 12;
+
     /* Write the tables. */
 
     for ( nn = 0; nn < woff.num_tables; nn++ )
@@ -651,6 +676,7 @@
           goto Exit;
         if ( output_len != table->OrigLength )
         {
+          FT_ERROR(( "woff_font_open: compressed table length mismatch\n" ));
           error = FT_THROW( Invalid_Table );
           goto Exit;
         }
@@ -778,6 +804,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 );
 
@@ -852,6 +881,21 @@
 
     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 );
+    }
+
+    FT_FACE_FIND_GLOBAL_SERVICE( face, face->var, METRICS_VARIATIONS );
+#endif
+
     FT_TRACE2(( "SFNT driver\n" ));
 
     error = sfnt_open_font( stream, face );
@@ -861,10 +905,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 )
@@ -883,18 +931,66 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     {
-      FT_ULong   fvar_len;
-      FT_UShort  num_instances;
-      FT_Int     instance_index;
+      FT_ULong  fvar_len;
 
+      FT_ULong  version;
+      FT_ULong  offset;
+
+      FT_UShort  num_axes;
+      FT_UShort  axis_size;
+      FT_UShort  num_instances;
+      FT_UShort  instance_size;
+
+      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 */
       if ( face->goto_table( face, TTAG_fvar, stream, &fvar_len ) ||
            fvar_len < 20                                          ||
-           FT_STREAM_SKIP( 12 )                                   ||
-           FT_READ_USHORT( num_instances )                        )
+           FT_READ_ULONG( version )                               ||
+           FT_READ_USHORT( offset )                               ||
+           FT_STREAM_SKIP( 2 ) /* count_size_pairs */             ||
+           FT_READ_USHORT( num_axes )                             ||
+           FT_READ_USHORT( axis_size )                            ||
+           FT_READ_USHORT( num_instances )                        ||
+           FT_READ_USHORT( instance_size )                        )
+      {
+        version       = 0;
+        offset        = 0;
+        num_axes      = 0;
+        axis_size     = 0;
+        num_instances = 0;
+        instance_size = 0;
+      }
+
+      /* 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 == 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 ) )
         num_instances = 0;
 
       /* we support at most 2^15 - 1 instances */
@@ -921,7 +1017,7 @@
 #endif
 
     face->root.num_faces  = face->ttc_header.count;
-    face->root.face_index = face_index;
+    face->root.face_index = face_instance_index;
 
     return error;
   }
@@ -1027,12 +1123,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;
@@ -1164,30 +1262,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 );
 
@@ -1271,10 +1349,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;
@@ -1337,7 +1419,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 */
@@ -1355,7 +1437,7 @@
        *  depths in the FT_Bitmap_Size record.  This is a design error.
        */
       {
-        FT_UInt  i, count;
+        FT_UInt  count;
 
 
         count = face->sbit_num_strikes;
@@ -1367,6 +1449,9 @@
           FT_Short         avgwidth = face->os2.xAvgCharWidth;
           FT_Size_Metrics  metrics;
 
+          FT_UInt*  sbit_strike_map = NULL;
+          FT_UInt   strike_idx, bsize_idx;
+
 
           if ( em_size == 0 || face->os2.version == 0xFFFFU )
           {
@@ -1374,31 +1459,50 @@
             em_size = 1;
           }
 
-          if ( FT_NEW_ARRAY( root->available_sizes, count ) )
+          /* to avoid invalid strike data in the `available_sizes' field */
+          /* of `FT_Face', we map `available_sizes' indices to strike    */
+          /* indices                                                     */
+          if ( FT_NEW_ARRAY( root->available_sizes, count ) ||
+               FT_NEW_ARRAY( sbit_strike_map, count ) )
             goto Exit;
 
-          for ( i = 0; i < count; i++ )
+          bsize_idx = 0;
+          for ( strike_idx = 0; strike_idx < count; strike_idx++ )
           {
-            FT_Bitmap_Size*  bsize = root->available_sizes + i;
+            FT_Bitmap_Size*  bsize = root->available_sizes + bsize_idx;
 
 
-            error = sfnt->load_strike_metrics( face, i, &metrics );
+            error = sfnt->load_strike_metrics( face, strike_idx, &metrics );
             if ( error )
-              goto Exit;
+              continue;
 
             bsize->height = (FT_Short)( metrics.height >> 6 );
-            bsize->width = (FT_Short)(
-                ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size );
+            bsize->width  = (FT_Short)(
+              ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size );
 
             bsize->x_ppem = metrics.x_ppem << 6;
             bsize->y_ppem = metrics.y_ppem << 6;
 
             /* assume 72dpi */
             bsize->size   = metrics.y_ppem << 6;
+
+            /* only use strikes with valid PPEM values */
+            if ( bsize->x_ppem && bsize->y_ppem )
+              sbit_strike_map[bsize_idx++] = strike_idx;
           }
 
-          root->face_flags     |= FT_FACE_FLAG_FIXED_SIZES;
-          root->num_fixed_sizes = (FT_Int)count;
+          /* reduce array size to the actually used elements */
+          (void)FT_RENEW_ARRAY( sbit_strike_map, count, bsize_idx );
+
+          /* from now on, all strike indices are mapped */
+          /* using `sbit_strike_map'                    */
+          if ( bsize_idx )
+          {
+            face->sbit_strike_map = sbit_strike_map;
+
+            root->face_flags     |= FT_FACE_FLAG_FIXED_SIZES;
+            root->num_fixed_sizes = (FT_Int)bsize_idx;
+          }
         }
       }
 
@@ -1559,18 +1663,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  );
@@ -1592,6 +1688,7 @@
 
     /* freeing sbit size table */
     FT_FREE( face->root.available_sizes );
+    FT_FREE( face->sbit_strike_map );
     face->root.num_fixed_sizes = 0;
 
     FT_FREE( face->postscript_name );
diff --git a/third_party/freetype/src/sfnt/sfobjs.h b/third_party/freetype/src/sfnt/sfobjs.h
index 455f867..7053814 100644
--- a/third_party/freetype/src/sfnt/sfobjs.h
+++ b/third_party/freetype/src/sfnt/sfobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    SFNT object management (specification).                              */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __SFOBJS_H__
-#define __SFOBJS_H__
+#ifndef SFOBJS_H_
+#define SFOBJS_H_
 
 
 #include <ft2build.h>
@@ -53,7 +53,7 @@
 
 FT_END_HEADER
 
-#endif /* __SFDRIVER_H__ */
+#endif /* SFDRIVER_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/sfnt/ttcmap.c b/third_party/freetype/src/sfnt/ttcmap.c
index c4d9abd..5afa6ae 100644
--- a/third_party/freetype/src/sfnt/ttcmap.c
+++ b/third_party/freetype/src/sfnt/ttcmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType character mapping table (cmap) support (body).              */
 /*                                                                         */
-/*  Copyright 2002-2015 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 */
 
@@ -763,6 +767,9 @@
   static void
   tt_cmap4_next( TT_CMap4  cmap )
   {
+    TT_Face   face  = (TT_Face)cmap->cmap.cmap.charmap.face;
+    FT_Byte*  limit = face->cmap_table + face->cmap_size;
+
     FT_UInt  charcode;
 
 
@@ -774,7 +781,7 @@
     if ( charcode < cmap->cur_start )
       charcode = cmap->cur_start;
 
-    for ( ;; )
+    for (;;)
     {
       FT_Byte*  values = cmap->cur_values;
       FT_UInt   end    = cmap->cur_end;
@@ -788,15 +795,19 @@
           FT_Byte*  p = values + 2 * ( charcode - cmap->cur_start );
 
 
+          /* if p > limit, the whole segment is invalid */
+          if ( p > limit )
+            goto Next_Segment;
+
           do
           {
             FT_UInt  gindex = FT_NEXT_USHORT( p );
 
 
-            if ( gindex != 0 )
+            if ( gindex )
             {
               gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
-              if ( gindex != 0 )
+              if ( gindex )
               {
                 cmap->cur_charcode = charcode;
                 cmap->cur_gindex   = gindex;
@@ -812,7 +823,26 @@
             FT_UInt  gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
 
 
-            if ( gindex != 0 )
+            if ( gindex >= (FT_UInt)face->root.num_glyphs )
+            {
+              /* we have an invalid glyph index; if there is an overflow, */
+              /* we can adjust `charcode', otherwise the whole segment is */
+              /* invalid                                                  */
+              gindex = 0;
+
+              if ( (FT_Int)charcode + delta < 0 &&
+                   (FT_Int)end + delta >= 0     )
+                charcode = (FT_UInt)( -delta );
+
+              else if ( (FT_Int)charcode + delta < 0x10000L &&
+                        (FT_Int)end + delta >= 0x10000L     )
+                charcode = (FT_UInt)( 0x10000L - delta );
+
+              else
+                goto Next_Segment;
+            }
+
+            if ( gindex )
             {
               cmap->cur_charcode = charcode;
               cmap->cur_gindex   = gindex;
@@ -822,6 +852,7 @@
         }
       }
 
+    Next_Segment:
       /* we need to find another range */
       if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 )
         break;
@@ -1170,6 +1201,9 @@
                             FT_UInt32*  pcharcode,
                             FT_Bool     next )
   {
+    TT_Face   face  = (TT_Face)cmap->cmap.charmap.face;
+    FT_Byte*  limit = face->cmap_table + face->cmap_size;
+
     FT_UInt   num_segs2, start, end, offset;
     FT_Int    delta;
     FT_UInt   max, min, mid, num_segs;
@@ -1221,10 +1255,6 @@
         if ( mid >= num_segs - 1                &&
              start == 0xFFFFU && end == 0xFFFFU )
         {
-          TT_Face   face  = (TT_Face)cmap->cmap.charmap.face;
-          FT_Byte*  limit = face->cmap_table + face->cmap_size;
-
-
           if ( offset && p + offset + 2 > limit )
           {
             delta  = 1;
@@ -1245,7 +1275,7 @@
             mid = max + 1;
 
           /* search in segments before the current segment */
-          for ( i = max ; i > 0; i-- )
+          for ( i = max; i > 0; i-- )
           {
             FT_UInt   prev_end;
             FT_Byte*  old_p;
@@ -1347,13 +1377,40 @@
         if ( offset )
         {
           p += offset + ( charcode - start ) * 2;
+
+          /* if p > limit, the whole segment is invalid */
+          if ( next && p > limit )
+            break;
+
           gindex = TT_PEEK_USHORT( p );
-          if ( gindex != 0 )
+          if ( gindex )
+          {
             gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
+            if ( gindex >= (FT_UInt)face->root.num_glyphs )
+              gindex = 0;
+          }
         }
         else
+        {
           gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
 
+          if ( next && gindex >= (FT_UInt)face->root.num_glyphs )
+          {
+            /* we have an invalid glyph index; if there is an overflow, */
+            /* we can adjust `charcode', otherwise the whole segment is */
+            /* invalid                                                  */
+            gindex = 0;
+
+            if ( (FT_Int)charcode + delta < 0 &&
+                 (FT_Int)end + delta >= 0     )
+              charcode = (FT_UInt)( -delta );
+
+            else if ( (FT_Int)charcode + delta < 0x10000L &&
+                      (FT_Int)end + delta >= 0x10000L     )
+              charcode = (FT_UInt)( 0x10000L - delta );
+          }
+        }
+
         break;
       }
     }
@@ -1463,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 */
 
@@ -1630,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 */
 
@@ -1891,7 +1953,10 @@
         /* if `gindex' is invalid, the remaining values */
         /* in this group are invalid, too               */
         if ( gindex >= (FT_UInt)face->num_glyphs )
+        {
+          gindex = 0;
           continue;
+        }
 
         result = char_code;
         break;
@@ -1919,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 */
 
@@ -2089,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 */
 
@@ -2277,7 +2346,10 @@
         /* if `gindex' is invalid, the remaining values */
         /* in this group are invalid, too               */
         if ( gindex >= (FT_UInt)face->num_glyphs )
+        {
+          gindex = 0;
           continue;
+        }
 
         cmap->cur_charcode = char_code;
         cmap->cur_gindex   = gindex;
@@ -2440,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 */
 
@@ -2764,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 */
 
@@ -2870,7 +2946,7 @@
 
 
     cmap->max_results = 0;
-    if ( memory != NULL && cmap->results != NULL )
+    if ( memory && cmap->results )
       FT_FREE( cmap->results );
   }
 
@@ -2962,17 +3038,22 @@
         /* through the normal Unicode cmap, no GIDs, just check order) */
         if ( defOff != 0 )
         {
-          FT_Byte*  defp      = table + defOff;
-          FT_ULong  numRanges = TT_NEXT_ULONG( defp );
+          FT_Byte*  defp     = table + defOff;
+          FT_ULong  numRanges;
           FT_ULong  i;
-          FT_ULong  lastBase  = 0;
+          FT_ULong  lastBase = 0;
 
 
+          if ( defp + 4 > valid->limit )
+            FT_INVALID_TOO_SHORT;
+
+          numRanges = TT_NEXT_ULONG( defp );
+
           /* defp + numRanges * 4 > valid->limit ? */
           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 );
@@ -2991,16 +3072,21 @@
         /* and the non-default table (these glyphs are specified here) */
         if ( nondefOff != 0 )
         {
-          FT_Byte*  ndp         = table + nondefOff;
-          FT_ULong  numMappings = TT_NEXT_ULONG( ndp );
-          FT_ULong  i, lastUni  = 0;
+          FT_Byte*  ndp        = table + nondefOff;
+          FT_ULong  numMappings;
+          FT_ULong  i, lastUni = 0;
 
 
-          /* numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ? */
-          if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 4 )
+          if ( ndp + 4 > valid->limit )
             FT_INVALID_TOO_SHORT;
 
-          for ( i = 0; i < numMappings; ++i )
+          numMappings = TT_NEXT_ULONG( ndp );
+
+          /* numMappings * 5 > (FT_ULong)( valid->limit - ndp ) ? */
+          if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 5 )
+            FT_INVALID_TOO_SHORT;
+
+          for ( i = 0; i < numMappings; i++ )
           {
             FT_ULong  uni = TT_NEXT_UINT24( ndp );
             FT_ULong  gid = TT_NEXT_USHORT( ndp );
@@ -3088,7 +3174,7 @@
 
       if ( char_code < start )
         max = mid;
-      else if ( char_code > start+cnt )
+      else if ( char_code > start + cnt )
         min = mid + 1;
       else
         return TRUE;
@@ -3241,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;
@@ -3266,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 );
@@ -3325,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 );
 
@@ -3362,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;
@@ -3442,14 +3528,14 @@
       ni   = 1;
       i    = 0;
 
-      for ( ;; )
+      for (;;)
       {
         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;
@@ -3463,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;
 
@@ -3482,7 +3568,7 @@
         {
           ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p );
           p += 2;
-          ++ni;
+          ni++;
         }
       }
       else if ( di <= numRanges )
@@ -3490,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 )
@@ -3498,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++;
         }
       }
 
@@ -3513,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 */
 
@@ -3668,7 +3756,7 @@
               error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );
             }
 
-            if ( valid.validator.error == 0 )
+            if ( !valid.validator.error )
             {
               FT_CMap  ttcmap;
 
@@ -3694,7 +3782,7 @@
           }
         }
 
-        if ( *pclazz == NULL )
+        if ( !*pclazz )
         {
           FT_TRACE0(( "tt_face_build_cmaps:"
                       " unsupported cmap sub-table ignored\n" ));
diff --git a/third_party/freetype/src/sfnt/ttcmap.h b/third_party/freetype/src/sfnt/ttcmap.h
index b7ea8ee..83f12df 100644
--- a/third_party/freetype/src/sfnt/ttcmap.h
+++ b/third_party/freetype/src/sfnt/ttcmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType character mapping table (cmap) support (specification).     */
 /*                                                                         */
-/*  Copyright 2002-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTCMAP_H__
-#define __TTCMAP_H__
+#ifndef TTCMAP_H_
+#define TTCMAP_H_
 
 
 #include <ft2build.h>
@@ -152,7 +152,7 @@
 
 FT_END_HEADER
 
-#endif /* __TTCMAP_H__ */
+#endif /* TTCMAP_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/sfnt/ttcmapc.h b/third_party/freetype/src/sfnt/ttcmapc.h
index 4a48940..9a5e708 100644
--- a/third_party/freetype/src/sfnt/ttcmapc.h
+++ b/third_party/freetype/src/sfnt/ttcmapc.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TT CMAP classes definitions (specification only).                    */
 /*                                                                         */
-/*  Copyright 2009-2015 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/third_party/freetype/src/sfnt/ttkern.c b/third_party/freetype/src/sfnt/ttkern.c
index 4fccc53..78dc5eb 100644
--- a/third_party/freetype/src/sfnt/ttkern.c
+++ b/third_party/freetype/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-2015 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/third_party/freetype/src/sfnt/ttkern.h b/third_party/freetype/src/sfnt/ttkern.h
index 89cb24f..db1a30b 100644
--- a/third_party/freetype/src/sfnt/ttkern.h
+++ b/third_party/freetype/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-2015 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,       */
@@ -17,8 +17,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTKERN_H__
-#define __TTKERN_H__
+#ifndef TTKERN_H_
+#define TTKERN_H_
 
 
 #include <ft2build.h>
@@ -46,7 +46,7 @@
 
 FT_END_HEADER
 
-#endif /* __TTKERN_H__ */
+#endif /* TTKERN_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/sfnt/ttload.c b/third_party/freetype/src/sfnt/ttload.c
index c1bd7f0..53837c7 100644
--- a/third_party/freetype/src/sfnt/ttload.c
+++ b/third_party/freetype/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-2015 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.                      */
@@ -775,15 +775,6 @@
 
         maxProfile->maxTwilightPoints = 0xFFFFU - 4;
       }
-
-      /* we arbitrarily limit recursion to avoid stack exhaustion */
-      if ( maxProfile->maxComponentDepth > 100 )
-      {
-        FT_TRACE0(( "tt_face_load_maxp:"
-                    " abnormally large component depth (%d) set to 100\n",
-                    maxProfile->maxComponentDepth ));
-        maxProfile->maxComponentDepth = 100;
-      }
     }
 
     FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs ));
@@ -1193,8 +1184,8 @@
 #define FT_STRUCTURE  TT_Postscript
 
       FT_FRAME_START( 32 ),
-        FT_FRAME_ULONG( FormatType ),
-        FT_FRAME_ULONG( italicAngle ),
+        FT_FRAME_LONG ( FormatType ),
+        FT_FRAME_LONG ( italicAngle ),
         FT_FRAME_SHORT( underlinePosition ),
         FT_FRAME_SHORT( underlineThickness ),
         FT_FRAME_ULONG( isFixedPitch ),
diff --git a/third_party/freetype/src/sfnt/ttload.h b/third_party/freetype/src/sfnt/ttload.h
index a6d91c5..296da86 100644
--- a/third_party/freetype/src/sfnt/ttload.h
+++ b/third_party/freetype/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-2015 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,       */
@@ -17,8 +17,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTLOAD_H__
-#define __TTLOAD_H__
+#ifndef TTLOAD_H_
+#define TTLOAD_H_
 
 
 #include <ft2build.h>
@@ -106,7 +106,7 @@
 
 FT_END_HEADER
 
-#endif /* __TTLOAD_H__ */
+#endif /* TTLOAD_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/sfnt/ttmtx.c b/third_party/freetype/src/sfnt/ttmtx.c
index 58309aa..f2e5541 100644
--- a/third_party/freetype/src/sfnt/ttmtx.c
+++ b/third_party/freetype/src/sfnt/ttmtx.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Load the metrics tables common to TTF and OTF fonts (body).          */
 /*                                                                         */
-/*  Copyright 2006-2015 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,6 +20,11 @@
 #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"
@@ -214,6 +219,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 +284,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/third_party/freetype/src/sfnt/ttmtx.h b/third_party/freetype/src/sfnt/ttmtx.h
index 096ee06..2b93ab2 100644
--- a/third_party/freetype/src/sfnt/ttmtx.h
+++ b/third_party/freetype/src/sfnt/ttmtx.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Load the metrics tables common to TTF and OTF fonts (specification). */
 /*                                                                         */
-/*  Copyright 2006-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTMTX_H__
-#define __TTMTX_H__
+#ifndef TTMTX_H_
+#define TTMTX_H_
 
 
 #include <ft2build.h>
@@ -49,7 +49,7 @@
 
 FT_END_HEADER
 
-#endif /* __TTMTX_H__ */
+#endif /* TTMTX_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/sfnt/ttpost.c b/third_party/freetype/src/sfnt/ttpost.c
index 8d29d1e..6548e85 100644
--- a/third_party/freetype/src/sfnt/ttpost.c
+++ b/third_party/freetype/src/sfnt/ttpost.c
@@ -2,10 +2,10 @@
 /*                                                                         */
 /*  ttpost.c                                                               */
 /*                                                                         */
-/*    Postcript name table processing for TrueType and OpenType fonts      */
+/*    PostScript name table processing for TrueType and OpenType fonts     */
 /*    (body).                                                              */
 /*                                                                         */
-/*  Copyright 1996-2015 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/third_party/freetype/src/sfnt/ttpost.h b/third_party/freetype/src/sfnt/ttpost.h
index e3eca02..722485e 100644
--- a/third_party/freetype/src/sfnt/ttpost.h
+++ b/third_party/freetype/src/sfnt/ttpost.h
@@ -2,10 +2,10 @@
 /*                                                                         */
 /*  ttpost.h                                                               */
 /*                                                                         */
-/*    Postcript name table processing for TrueType and OpenType fonts      */
+/*    PostScript name table processing for TrueType and OpenType fonts     */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -17,8 +17,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTPOST_H__
-#define __TTPOST_H__
+#ifndef TTPOST_H_
+#define TTPOST_H_
 
 
 #include <ft2build.h>
@@ -40,7 +40,7 @@
 
 FT_END_HEADER
 
-#endif /* __TTPOST_H__ */
+#endif /* TTPOST_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/smooth/ftgrays.c b/third_party/freetype/src/smooth/ftgrays.c
index ba29445..9982f72 100644
--- a/third_party/freetype/src/smooth/ftgrays.c
+++ b/third_party/freetype/src/smooth/ftgrays.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    A new `perfect' anti-aliasing renderer (body).                       */
 /*                                                                         */
-/*  Copyright 2000-2015 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,       */
@@ -18,7 +18,7 @@
   /*************************************************************************/
   /*                                                                       */
   /* This file can be compiled without the rest of the FreeType engine, by */
-  /* defining the _STANDALONE_ macro when compiling it.  You also need to  */
+  /* defining the STANDALONE_ macro when compiling it.  You also need to   */
   /* put the files `ftgrays.h' and `ftimage.h' into the current            */
   /* compilation directory.  Typically, you could do something like        */
   /*                                                                       */
@@ -27,9 +27,9 @@
   /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */
   /*   same directory                                                      */
   /*                                                                       */
-  /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in        */
+  /* - compile `ftgrays' with the STANDALONE_ macro defined, as in         */
   /*                                                                       */
-  /*     cc -c -D_STANDALONE_ ftgrays.c                                    */
+  /*     cc -c -DSTANDALONE_ ftgrays.c                                     */
   /*                                                                       */
   /* The renderer can be initialized with a call to                        */
   /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated  */
@@ -91,7 +91,7 @@
 #define FT_COMPONENT  trace_smooth
 
 
-#ifdef _STANDALONE_
+#ifdef STANDALONE_
 
 
   /* The size in bytes of the render pool used by the scan-line converter  */
@@ -106,6 +106,7 @@
 #define FT_BEGIN_STMNT  do {
 #define FT_END_STMNT    } while ( 0 )
 
+#define FT_MIN( a, b )  ( (a) < (b) ? (a) : (b) )
 #define FT_MAX( a, b )  ( (a) > (b) ? (a) : (b) )
 #define FT_ABS( a )     ( (a) < 0 ? -(a) : (a) )
 
@@ -135,8 +136,10 @@
 #include <string.h>
 #include <setjmp.h>
 #include <limits.h>
-#define FT_UINT_MAX  UINT_MAX
-#define FT_INT_MAX   INT_MAX
+#define FT_CHAR_BIT   CHAR_BIT
+#define FT_UINT_MAX   UINT_MAX
+#define FT_INT_MAX    INT_MAX
+#define FT_ULONG_MAX  ULONG_MAX
 
 #define ft_memset   memset
 
@@ -254,7 +257,7 @@
          };
 
 
-#else /* !_STANDALONE_ */
+#else /* !STANDALONE_ */
 
 
 #include <ft2build.h>
@@ -272,7 +275,7 @@
 #define ErrRaster_Memory_Overflow   Smooth_Err_Out_Of_Memory
 
 
-#endif /* !_STANDALONE_ */
+#endif /* !STANDALONE_ */
 
 
 #ifndef FT_MEM_SET
@@ -283,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
@@ -300,7 +307,7 @@
 
 #else /* FT_STATIC_RASTER */
 
-#define RAS_ARG   /* empty */
+#define RAS_ARG   void
 #define RAS_ARG_  /* empty */
 #define RAS_VAR   /* empty */
 #define RAS_VAR_  /* empty */
@@ -316,19 +323,19 @@
 #undef TRUNC
 #undef SCALED
 
-#define ONE_PIXEL       ( 1L << PIXEL_BITS )
+#define ONE_PIXEL       ( 1 << PIXEL_BITS )
 #define TRUNC( x )      ( (TCoord)( (x) >> PIXEL_BITS ) )
-#define SUBPIXELS( x )  ( (TPos)(x) << PIXEL_BITS )
+#define SUBPIXELS( x )  ( (TPos)(x) * ONE_PIXEL )
 #define FLOOR( x )      ( (x) & -ONE_PIXEL )
 #define CEILING( x )    ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
 #define ROUND( x )      ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )
 
 #if PIXEL_BITS >= 6
-#define UPSCALE( x )    ( (x) << ( PIXEL_BITS - 6 ) )
+#define UPSCALE( x )    ( (x) * ( ONE_PIXEL >> 6 ) )
 #define DOWNSCALE( x )  ( (x) >> ( PIXEL_BITS - 6 ) )
 #else
 #define UPSCALE( x )    ( (x) >> ( 6 - PIXEL_BITS ) )
-#define DOWNSCALE( x )  ( (x) << ( 6 - PIXEL_BITS ) )
+#define DOWNSCALE( x )  ( (x) * ( 64 >> PIXEL_BITS ) )
 #endif
 
 
@@ -366,6 +373,16 @@
 #endif /* __arm__ */
 
 
+  /* These macros speed up repetitive divisions by replacing them */
+  /* with multiplications and right shifts.                       */
+#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 ) )
+
+
   /*************************************************************************/
   /*                                                                       */
   /*   TYPE DEFINITIONS                                                    */
@@ -375,44 +392,36 @@
   /* need to define them to "float" or "double" when experimenting with   */
   /* new algorithms                                                       */
 
-  typedef long  TCoord;   /* integer scanline/pixel coordinate */
   typedef long  TPos;     /* sub-pixel coordinate              */
-
-  /* determine the type used to store cell areas.  This normally takes at */
-  /* least PIXEL_BITS*2 + 1 bits.  On 16-bit systems, we need to use      */
-  /* `long' instead of `int', otherwise bad things happen                 */
-
-#if PIXEL_BITS <= 7
-
-  typedef int  TArea;
-
-#else /* PIXEL_BITS >= 8 */
-
-  /* approximately determine the size of integers using an ANSI-C header */
-#if FT_UINT_MAX == 0xFFFFU
-  typedef long  TArea;
-#else
-  typedef int   TArea;
-#endif
-
-#endif /* PIXEL_BITS >= 8 */
-
-
-  /* maximum number of gray spans in a call to the span callback */
-#define FT_MAX_GRAY_SPANS  32
+  typedef int   TCoord;   /* integer scanline/pixel coordinate */
+  typedef int   TArea;    /* cell areas, coordinate products   */
 
 
   typedef struct TCell_*  PCell;
 
   typedef struct  TCell_
   {
-    TPos    x;     /* same with gray_TWorker.ex    */
+    TCoord  x;     /* same with gray_TWorker.ex    */
     TCoord  cover; /* same with gray_TWorker.cover */
     TArea   area;
     PCell   next;
 
   } TCell;
 
+  typedef struct TPixmap_
+  {
+    unsigned char*  origin;  /* pixmap origin at the bottom-left */
+    int             pitch;   /* pitch to go down one row */
+
+  } TPixmap;
+
+  /* maximum number of gray cells in the buffer */
+#if FT_RENDER_POOL_SIZE > 2048
+#define FT_MAX_GRAY_POOL  ( FT_RENDER_POOL_SIZE / sizeof ( TCell ) )
+#else
+#define FT_MAX_GRAY_POOL  ( 2048 / sizeof ( TCell ) )
+#endif
+
 
 #if defined( _MSC_VER )      /* Visual C++ (and Intel C++) */
   /* We disable the warning `structure was padded due to   */
@@ -427,42 +436,25 @@
     ft_jmp_buf  jump_buffer;
 
     TCoord  ex, ey;
-    TPos    min_ex, max_ex;
-    TPos    min_ey, max_ey;
-    TPos    count_ex, count_ey;
+    TCoord  min_ex, max_ex;
+    TCoord  min_ey, max_ey;
 
     TArea   area;
     TCoord  cover;
     int     invalid;
 
+    PCell*      ycells;
     PCell       cells;
     FT_PtrDist  max_cells;
     FT_PtrDist  num_cells;
 
     TPos    x,  y;
 
-    FT_Vector   bez_stack[32 * 3 + 1];
-    int         lev_stack[32];
-
     FT_Outline  outline;
-    FT_Bitmap   target;
-    FT_BBox     clip_box;
-
-    FT_Span     gray_spans[FT_MAX_GRAY_SPANS];
-    int         num_gray_spans;
+    TPixmap     target;
 
     FT_Raster_Span_Func  render_span;
     void*                render_span_data;
-    int                  span_y;
-
-    int  band_size;
-    int  band_shoot;
-
-    void*       buffer;
-    long        buffer_size;
-
-    PCell*     ycells;
-    TPos       ycount;
 
   } gray_TWorker, *gray_PWorker;
 
@@ -485,95 +477,53 @@
   } gray_TRaster, *gray_PRaster;
 
 
+#ifdef FT_DEBUG_LEVEL_TRACE
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Initialize the cells table.                                           */
-  /*                                                                       */
+  /* to be called while in the debugger --                                */
+  /* this function causes a compiler warning since it is unused otherwise */
   static void
-  gray_init_cells( RAS_ARG_ void*  buffer,
-                            long   byte_size )
+  gray_dump_cells( RAS_ARG )
   {
-    ras.buffer      = buffer;
-    ras.buffer_size = byte_size;
+    int  y;
 
-    ras.ycells      = (PCell*) buffer;
-    ras.cells       = NULL;
-    ras.max_cells   = 0;
-    ras.num_cells   = 0;
-    ras.area        = 0;
-    ras.cover       = 0;
-    ras.invalid     = 1;
+
+    for ( y = ras.min_ey; y < ras.max_ey; y++ )
+    {
+      PCell  cell = ras.ycells[y - ras.min_ey];
+
+
+      printf( "%3d:", y );
+
+      for ( ; cell != NULL; cell = cell->next )
+        printf( " (%3d, c:%4d, a:%6d)",
+                cell->x, cell->cover, cell->area );
+      printf( "\n" );
+    }
   }
 
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Compute the outline bounding box.                                     */
-  /*                                                                       */
-  static void
-  gray_compute_cbox( RAS_ARG )
-  {
-    FT_Outline*  outline = &ras.outline;
-    FT_Vector*   vec     = outline->points;
-    FT_Vector*   limit   = vec + outline->n_points;
-
-
-    if ( outline->n_points <= 0 )
-    {
-      ras.min_ex = ras.max_ex = 0;
-      ras.min_ey = ras.max_ey = 0;
-      return;
-    }
-
-    ras.min_ex = ras.max_ex = vec->x;
-    ras.min_ey = ras.max_ey = vec->y;
-
-    vec++;
-
-    for ( ; vec < limit; vec++ )
-    {
-      TPos  x = vec->x;
-      TPos  y = vec->y;
-
-
-      if ( x < ras.min_ex ) ras.min_ex = x;
-      if ( x > ras.max_ex ) ras.max_ex = x;
-      if ( y < ras.min_ey ) ras.min_ey = y;
-      if ( y > ras.max_ey ) ras.max_ey = y;
-    }
-
-    /* truncate the bounding box to integer pixels */
-    ras.min_ex = ras.min_ex >> 6;
-    ras.min_ey = ras.min_ey >> 6;
-    ras.max_ex = ( ras.max_ex + 63 ) >> 6;
-    ras.max_ey = ( ras.max_ey + 63 ) >> 6;
-  }
+#endif /* FT_DEBUG_LEVEL_TRACE */
 
 
   /*************************************************************************/
   /*                                                                       */
   /* Record the current cell in the table.                                 */
   /*                                                                       */
-  static PCell
-  gray_find_cell( RAS_ARG )
+  static void
+  gray_record_cell( RAS_ARG )
   {
     PCell  *pcell, cell;
-    TPos    x = ras.ex;
+    TCoord  x = ras.ex;
 
 
-    if ( x > ras.count_ex )
-      x = ras.count_ex;
-
-    pcell = &ras.ycells[ras.ey];
+    pcell = &ras.ycells[ras.ey - ras.min_ey];
     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;
     }
@@ -581,30 +531,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;
   }
 
 
@@ -628,57 +569,26 @@
 
     /* All cells that are on the left of the clipping region go to the */
     /* min_ex - 1 horizontal position.                                 */
-    ey -= ras.min_ey;
-
-    if ( ex > ras.max_ex )
-      ex = ras.max_ex;
-
-    ex -= ras.min_ex;
-    if ( ex < 0 )
-      ex = -1;
-
-    /* are we moving to a different cell ? */
-    if ( ex != ras.ex || ey != ras.ey )
-    {
-      /* record the current one if it is valid */
-      if ( !ras.invalid )
-        gray_record_cell( RAS_VAR );
-
-      ras.area  = 0;
-      ras.cover = 0;
-      ras.ex    = ex;
-      ras.ey    = ey;
-    }
-
-    ras.invalid = ( (unsigned int)ey >= (unsigned int)ras.count_ey ||
-                                  ex >= ras.count_ex               );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Start a new contour at a given cell.                                  */
-  /*                                                                       */
-  static void
-  gray_start_cell( RAS_ARG_ TCoord  ex,
-                            TCoord  ey )
-  {
-    if ( ex > ras.max_ex )
-      ex = (TCoord)( ras.max_ex );
 
     if ( ex < ras.min_ex )
-      ex = (TCoord)( ras.min_ex - 1 );
+      ex = ras.min_ex - 1;
 
-    ras.area    = 0;
-    ras.cover   = 0;
-    ras.ex      = ex - ras.min_ex;
-    ras.ey      = ey - ras.min_ey;
-    ras.invalid = 0;
+    /* record the current one if it is valid */
+    if ( !ras.invalid )
+      gray_record_cell( RAS_VAR );
 
-    gray_set_cell( RAS_VAR_ ex, ey );
+    ras.area  = 0;
+    ras.cover = 0;
+    ras.ex    = ex;
+    ras.ey    = ey;
+
+    ras.invalid = ( ey >= ras.max_ey || ey < ras.min_ey ||
+                    ex >= ras.max_ex );
   }
 
 
+#ifndef FT_LONG64
+
   /*************************************************************************/
   /*                                                                       */
   /* Render a scanline as one or more cells.                               */
@@ -690,17 +600,13 @@
                                  TPos    x2,
                                  TCoord  y2 )
   {
-    TCoord  ex1, ex2, fx1, fx2, delta, mod;
-    long    p, first, dx;
+    TCoord  ex1, ex2, fx1, fx2, first, delta, mod;
+    TPos    p, dx;
     int     incr;
 
 
-    dx = x2 - x1;
-
     ex1 = TRUNC( x1 );
     ex2 = TRUNC( x2 );
-    fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) );
-    fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) );
 
     /* trivial case.  Happens often */
     if ( y1 == y2 )
@@ -709,11 +615,14 @@
       return;
     }
 
+    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 )
     {
-      delta      = y2 - y1;
       ras.area  += (TArea)(( fx1 + fx2 ) * delta);
       ras.cover += delta;
       return;
@@ -722,13 +631,17 @@
     /* ok, we'll have to render a run of adjacent cells on the same */
     /* scanline...                                                  */
     /*                                                              */
-    p     = ( ONE_PIXEL - fx1 ) * ( y2 - y1 );
-    first = ONE_PIXEL;
-    incr  = 1;
+    dx = x2 - x1;
 
-    if ( dx < 0 )
+    if ( dx > 0 )
     {
-      p     = fx1 * ( y2 - y1 );
+      p     = ( ONE_PIXEL - fx1 ) * delta;
+      first = ONE_PIXEL;
+      incr  = 1;
+    }
+    else
+    {
+      p     = fx1 * delta;
       first = 0;
       incr  = -1;
       dx    = -dx;
@@ -785,25 +698,22 @@
   gray_render_line( RAS_ARG_ TPos  to_x,
                              TPos  to_y )
   {
-    TCoord  ey1, ey2, fy1, fy2, mod;
-    TPos    dx, dy, x, x2;
-    long    p, first;
-    int     delta, rem, lift, incr;
+    TCoord  ey1, ey2, fy1, fy2, first, delta, mod;
+    TPos    p, dx, dy, x, x2;
+    int     incr;
 
 
     ey1 = TRUNC( ras.y );
     ey2 = TRUNC( to_y );     /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */
-    fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) );
-    fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
-
-    dx = to_x - ras.x;
-    dy = to_y - ras.y;
 
     /* perform vertical clipping */
     if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) ||
          ( ey1 <  ras.min_ey && ey2 <  ras.min_ey ) )
       goto End;
 
+    fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) );
+    fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
+
     /* everything is on a single scanline */
     if ( ey1 == ey2 )
     {
@@ -811,9 +721,10 @@
       goto End;
     }
 
-    /* vertical line - avoid calling gray_render_scanline */
-    incr = 1;
+    dx = to_x - ras.x;
+    dy = to_y - ras.y;
 
+    /* vertical line - avoid calling gray_render_scanline */
     if ( dx == 0 )
     {
       TCoord  ex     = TRUNC( ras.x );
@@ -821,21 +732,25 @@
       TArea   area;
 
 
-      first = ONE_PIXEL;
-      if ( dy < 0 )
+      if ( dy > 0)
+      {
+        first = ONE_PIXEL;
+        incr  = 1;
+      }
+      else
       {
         first = 0;
         incr  = -1;
       }
 
-      delta      = (int)( first - fy1 );
+      delta      = first - fy1;
       ras.area  += (TArea)two_fx * delta;
       ras.cover += delta;
       ey1       += incr;
 
       gray_set_cell( RAS_VAR_ ex, ey1 );
 
-      delta = (int)( first + first - ONE_PIXEL );
+      delta = first + first - ONE_PIXEL;
       area  = (TArea)two_fx * delta;
       while ( ey1 != ey2 )
       {
@@ -846,7 +761,7 @@
         gray_set_cell( RAS_VAR_ ex, ey1 );
       }
 
-      delta      = (int)( fy2 - ONE_PIXEL + first );
+      delta      = fy2 - ONE_PIXEL + first;
       ras.area  += (TArea)two_fx * delta;
       ras.cover += delta;
 
@@ -854,11 +769,13 @@
     }
 
     /* ok, we have to render several scanlines */
-    p     = ( ONE_PIXEL - fy1 ) * dx;
-    first = ONE_PIXEL;
-    incr  = 1;
-
-    if ( dy < 0 )
+    if ( dy > 0)
+    {
+      p     = ( ONE_PIXEL - fy1 ) * dx;
+      first = ONE_PIXEL;
+      incr  = 1;
+    }
+    else
     {
       p     = fy1 * dx;
       first = 0;
@@ -866,19 +783,22 @@
       dy    = -dy;
     }
 
-    FT_DIV_MOD( int, p, dy, delta, mod );
+    FT_DIV_MOD( TCoord, p, dy, delta, mod );
 
     x = ras.x + delta;
-    gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first );
+    gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, first );
 
     ey1 += incr;
     gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
 
     if ( ey1 != ey2 )
     {
-      p     = ONE_PIXEL * dx;
-      FT_DIV_MOD( int, p, dy, lift, rem );
-      mod -= (int)dy;
+      TCoord  lift, rem;
+
+
+      p    = ONE_PIXEL * dx;
+      FT_DIV_MOD( TCoord, p, dy, lift, rem );
+      mod -= (TCoord)dy;
 
       do
       {
@@ -886,14 +806,14 @@
         mod  += rem;
         if ( mod >= 0 )
         {
-          mod -= (int)dy;
+          mod -= (TCoord)dy;
           delta++;
         }
 
         x2 = x + delta;
-        gray_render_scanline( RAS_VAR_ ey1, x,
-                                       (TCoord)( ONE_PIXEL - first ), x2,
-                                       (TCoord)first );
+        gray_render_scanline( RAS_VAR_ ey1,
+                                       x, ONE_PIXEL - first,
+                                       x2, first );
         x = x2;
 
         ey1 += incr;
@@ -901,15 +821,153 @@
       } while ( ey1 != ey2 );
     }
 
-    gray_render_scanline( RAS_VAR_ ey1, x,
-                                   (TCoord)( ONE_PIXEL - first ), to_x,
-                                   fy2 );
+    gray_render_scanline( RAS_VAR_ ey1,
+                                   x, ONE_PIXEL - first,
+                                   to_x, fy2 );
 
   End:
     ras.x       = to_x;
     ras.y       = to_y;
   }
 
+#else
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Render a straight line across multiple cells in any direction.        */
+  /*                                                                       */
+  static void
+  gray_render_line( RAS_ARG_ TPos  to_x,
+                             TPos  to_y )
+  {
+    TPos    dx, dy, fx1, fy1, fx2, fy2;
+    TCoord  ex1, ex2, ey1, ey2;
+
+
+    ey1 = TRUNC( ras.y );
+    ey2 = TRUNC( to_y );
+
+    /* perform vertical clipping */
+    if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) ||
+         ( ey1 <  ras.min_ey && ey2 <  ras.min_ey ) )
+      goto End;
+
+    ex1 = TRUNC( ras.x );
+    ex2 = TRUNC( to_x );
+
+    fx1 = ras.x - SUBPIXELS( ex1 );
+    fy1 = ras.y - SUBPIXELS( ey1 );
+
+    dx = to_x - ras.x;
+    dy = to_y - ras.y;
+
+    if ( ex1 == ex2 && ey1 == ey2 )       /* inside one cell */
+      ;
+    else if ( dy == 0 ) /* ex1 != ex2 */  /* any horizontal line */
+    {
+      ex1 = ex2;
+      gray_set_cell( RAS_VAR_ ex1, ey1 );
+    }
+    else if ( dx == 0 )
+    {
+      if ( dy > 0 )                       /* vertical line up */
+        do
+        {
+          fy2 = ONE_PIXEL;
+          ras.cover += ( fy2 - fy1 );
+          ras.area  += ( fy2 - fy1 ) * fx1 * 2;
+          fy1 = 0;
+          ey1++;
+          gray_set_cell( RAS_VAR_ ex1, ey1 );
+        } while ( ey1 != ey2 );
+      else                                /* vertical line down */
+        do
+        {
+          fy2 = 0;
+          ras.cover += ( fy2 - fy1 );
+          ras.area  += ( fy2 - fy1 ) * fx1 * 2;
+          fy1 = ONE_PIXEL;
+          ey1--;
+          gray_set_cell( RAS_VAR_ ex1, ey1 );
+        } while ( ey1 != ey2 );
+    }
+    else                                  /* any other line */
+    {
+      TPos  prod = dx * fy1 - dy * fx1;
+      FT_UDIVPREP( ex1 != ex2, dx );
+      FT_UDIVPREP( ey1 != ey2, dy );
+
+
+      /* The fundamental value `prod' determines which side and the  */
+      /* exact coordinate where the line exits current cell.  It is  */
+      /* also easily updated when moving from one cell to the next.  */
+      do
+      {
+        if      ( prod                                   <= 0 &&
+                  prod - dx * ONE_PIXEL                  >  0 ) /* left */
+        {
+          fx2 = 0;
+          fy2 = (TPos)FT_UDIV( -prod, -dx );
+          prod -= dy * ONE_PIXEL;
+          ras.cover += ( fy2 - fy1 );
+          ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
+          fx1 = ONE_PIXEL;
+          fy1 = fy2;
+          ex1--;
+        }
+        else if ( prod - dx * ONE_PIXEL                  <= 0 &&
+                  prod - dx * ONE_PIXEL + dy * ONE_PIXEL >  0 ) /* up */
+        {
+          prod -= dx * ONE_PIXEL;
+          fx2 = (TPos)FT_UDIV( -prod, dy );
+          fy2 = ONE_PIXEL;
+          ras.cover += ( fy2 - fy1 );
+          ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
+          fx1 = fx2;
+          fy1 = 0;
+          ey1++;
+        }
+        else if ( prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 &&
+                  prod                  + dy * ONE_PIXEL >= 0 ) /* right */
+        {
+          prod += dy * ONE_PIXEL;
+          fx2 = ONE_PIXEL;
+          fy2 = (TPos)FT_UDIV( prod, dx );
+          ras.cover += ( fy2 - fy1 );
+          ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
+          fx1 = 0;
+          fy1 = fy2;
+          ex1++;
+        }
+        else /* ( prod                  + dy * ONE_PIXEL <  0 &&
+                  prod                                   >  0 )    down */
+        {
+          fx2 = (TPos)FT_UDIV( prod, -dy );
+          fy2 = 0;
+          prod += dx * ONE_PIXEL;
+          ras.cover += ( fy2 - fy1 );
+          ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
+          fx1 = fx2;
+          fy1 = ONE_PIXEL;
+          ey1--;
+        }
+
+        gray_set_cell( RAS_VAR_ ex1, ey1 );
+      } while ( ex1 != ex2 || ey1 != ey2 );
+    }
+
+    fx2 = to_x - SUBPIXELS( ex2 );
+    fy2 = to_y - SUBPIXELS( ey2 );
+
+    ras.cover += ( fy2 - fy1 );
+    ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
+
+  End:
+    ras.x       = to_x;
+    ras.y       = to_y;
+  }
+
+#endif
 
   static void
   gray_split_conic( FT_Vector*  base )
@@ -935,73 +993,64 @@
   gray_render_conic( RAS_ARG_ const FT_Vector*  control,
                               const FT_Vector*  to )
   {
+    FT_Vector   bez_stack[16 * 2 + 1];  /* enough to accommodate bisections */
+    FT_Vector*  arc = bez_stack;
     TPos        dx, dy;
-    TPos        min, max, y;
-    int         top, level;
-    int*        levels;
-    FT_Vector*  arc;
+    int         draw, split;
 
 
-    levels = ras.lev_stack;
-
-    arc      = ras.bez_stack;
     arc[0].x = UPSCALE( to->x );
     arc[0].y = UPSCALE( to->y );
     arc[1].x = UPSCALE( control->x );
     arc[1].y = UPSCALE( control->y );
     arc[2].x = ras.x;
     arc[2].y = ras.y;
-    top      = 0;
+
+    /* short-cut the arc that crosses the current band */
+    if ( ( TRUNC( arc[0].y ) >= ras.max_ey &&
+           TRUNC( arc[1].y ) >= ras.max_ey &&
+           TRUNC( arc[2].y ) >= ras.max_ey ) ||
+         ( TRUNC( arc[0].y ) <  ras.min_ey &&
+           TRUNC( arc[1].y ) <  ras.min_ey &&
+           TRUNC( arc[2].y ) <  ras.min_ey ) )
+    {
+      ras.x = arc[0].x;
+      ras.y = arc[0].y;
+      return;
+    }
 
     dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x );
     dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y );
     if ( dx < dy )
       dx = dy;
 
-    if ( dx < ONE_PIXEL / 4 )
-      goto Draw;
+    /* We can calculate the number of necessary bisections because  */
+    /* each bisection predictably reduces deviation exactly 4-fold. */
+    /* Even 32-bit deviation would vanish after 16 bisections.      */
+    draw = 1;
+    while ( dx > ONE_PIXEL / 4 )
+    {
+      dx   >>= 2;
+      draw <<= 1;
+    }
 
-    /* short-cut the arc that crosses the current band */
-    min = max = arc[0].y;
-
-    y = arc[1].y;
-    if ( y < min ) min = y;
-    if ( y > max ) max = y;
-
-    y = arc[2].y;
-    if ( y < min ) min = y;
-    if ( y > max ) max = y;
-
-    if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
-      goto Draw;
-
-    level = 0;
+    /* We use decrement counter to count the total number of segments */
+    /* to draw starting from 2^level. Before each draw we split as    */
+    /* many times as there are trailing zeros in the counter.         */
     do
     {
-      dx >>= 2;
-      level++;
-    } while ( dx > ONE_PIXEL / 4 );
-
-    levels[0] = level;
-
-    do
-    {
-      level = levels[top];
-      if ( level > 0 )
+      split = 1;
+      while ( ( draw & split ) == 0 )
       {
         gray_split_conic( arc );
         arc += 2;
-        top++;
-        levels[top] = levels[top - 1] = level - 1;
-        continue;
+        split <<= 1;
       }
 
-    Draw:
       gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
-      top--;
       arc -= 2;
 
-    } while ( top >= 0 );
+    } while ( --draw );
   }
 
 
@@ -1038,11 +1087,13 @@
                               const FT_Vector*  control2,
                               const FT_Vector*  to )
   {
-    FT_Vector*  arc;
-    TPos        min, max, y;
+    FT_Vector   bez_stack[16 * 3 + 1];  /* enough to accommodate bisections */
+    FT_Vector*  arc = bez_stack;
+    TPos        dx, dy, dx_, dy_;
+    TPos        dx1, dy1, dx2, dy2;
+    TPos        L, s, s_limit;
 
 
-    arc      = ras.bez_stack;
     arc[0].x = UPSCALE( to->x );
     arc[0].y = UPSCALE( to->y );
     arc[1].x = UPSCALE( control2->x );
@@ -1052,29 +1103,20 @@
     arc[3].x = ras.x;
     arc[3].y = ras.y;
 
-    /* Short-cut the arc that crosses the current band. */
-    min = max = arc[0].y;
-
-    y = arc[1].y;
-    if ( y < min )
-      min = y;
-    if ( y > max )
-      max = y;
-
-    y = arc[2].y;
-    if ( y < min )
-      min = y;
-    if ( y > max )
-      max = y;
-
-    y = arc[3].y;
-    if ( y < min )
-      min = y;
-    if ( y > max )
-      max = y;
-
-    if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
-      goto Draw;
+    /* short-cut the arc that crosses the current band */
+    if ( ( TRUNC( arc[0].y ) >= ras.max_ey &&
+           TRUNC( arc[1].y ) >= ras.max_ey &&
+           TRUNC( arc[2].y ) >= ras.max_ey &&
+           TRUNC( arc[3].y ) >= ras.max_ey ) ||
+         ( TRUNC( arc[0].y ) <  ras.min_ey &&
+           TRUNC( arc[1].y ) <  ras.min_ey &&
+           TRUNC( arc[2].y ) <  ras.min_ey &&
+           TRUNC( arc[3].y ) <  ras.min_ey ) )
+    {
+      ras.x = arc[0].x;
+      ras.y = arc[0].y;
+      return;
+    }
 
     for (;;)
     {
@@ -1083,64 +1125,53 @@
       /* F. Hain, at                                                      */
       /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */
 
-      {
-        TPos  dx, dy, dx_, dy_;
-        TPos  dx1, dy1, dx2, dy2;
-        TPos  L, s, s_limit;
+      /* dx and dy are x and y components of the P0-P3 chord vector. */
+      dx = dx_ = arc[3].x - arc[0].x;
+      dy = dy_ = arc[3].y - arc[0].y;
 
+      L = FT_HYPOT( dx_, dy_ );
 
-        /* dx and dy are x and y components of the P0-P3 chord vector. */
-        dx = dx_ = arc[3].x - arc[0].x;
-        dy = dy_ = arc[3].y - arc[0].y;
+      /* Avoid possible arithmetic overflow below by splitting. */
+      if ( L > 32767 )
+        goto Split;
 
-        L = FT_HYPOT( dx_, dy_ );
+      /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */
+      s_limit = L * (TPos)( ONE_PIXEL / 6 );
 
-        /* Avoid possible arithmetic overflow below by splitting. */
-        if ( L > 32767 )
-          goto Split;
+      /* s is L * the perpendicular distance from P1 to the line P0-P3. */
+      dx1 = arc[1].x - arc[0].x;
+      dy1 = arc[1].y - arc[0].y;
+      s = FT_ABS( dy * dx1 - dx * dy1 );
 
-        /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */
-        s_limit = L * (TPos)( ONE_PIXEL / 6 );
+      if ( s > s_limit )
+        goto Split;
 
-        /* s is L * the perpendicular distance from P1 to the line P0-P3. */
-        dx1 = arc[1].x - arc[0].x;
-        dy1 = arc[1].y - arc[0].y;
-        s = FT_ABS( dy * dx1 - dx * dy1 );
+      /* s is L * the perpendicular distance from P2 to the line P0-P3. */
+      dx2 = arc[2].x - arc[0].x;
+      dy2 = arc[2].y - arc[0].y;
+      s = FT_ABS( dy * dx2 - dx * dy2 );
 
-        if ( s > s_limit )
-          goto Split;
+      if ( s > s_limit )
+        goto Split;
 
-        /* s is L * the perpendicular distance from P2 to the line P0-P3. */
-        dx2 = arc[2].x - arc[0].x;
-        dy2 = arc[2].y - arc[0].y;
-        s = FT_ABS( dy * dx2 - dx * dy2 );
+      /* Split super curvy segments where the off points are so far
+         from the chord that the angles P0-P1-P3 or P0-P2-P3 become
+         acute as detected by appropriate dot products. */
+      if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 ||
+           dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 )
+        goto Split;
 
-        if ( s > s_limit )
-          goto Split;
+      gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
 
-        /* Split super curvy segments where the off points are so far
-           from the chord that the angles P0-P1-P3 or P0-P2-P3 become
-           acute as detected by appropriate dot products. */
-        if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 ||
-             dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 )
-          goto Split;
+      if ( arc == bez_stack )
+        return;
 
-        /* No reason to split. */
-        goto Draw;
-      }
+      arc -= 3;
+      continue;
 
     Split:
       gray_split_cubic( arc );
       arc += 3;
-      continue;
-
-    Draw:
-      gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
-
-      if ( arc == ras.bez_stack )
-        return;
-
-      arc -= 3;
     }
   }
 
@@ -1152,18 +1183,14 @@
     TPos  x, y;
 
 
-    /* record current cell, if any */
-    if ( !ras.invalid )
-      gray_record_cell( RAS_VAR );
-
     /* start to a new position */
     x = UPSCALE( to->x );
     y = UPSCALE( to->y );
 
-    gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) );
+    gray_set_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) );
 
-    worker->x = x;
-    worker->y = y;
+    ras.x = x;
+    ras.y = y;
     return 0;
   }
 
@@ -1199,63 +1226,13 @@
 
 
   static void
-  gray_render_span( int             y,
-                    int             count,
-                    const FT_Span*  spans,
-                    gray_PWorker    worker )
-  {
-    unsigned char*  p;
-    FT_Bitmap*      map = &worker->target;
-
-
-    /* first of all, compute the scanline offset */
-    p = (unsigned char*)map->buffer - y * map->pitch;
-    if ( map->pitch >= 0 )
-      p += ( map->rows - 1 ) * (unsigned int)map->pitch;
-
-    for ( ; count > 0; count--, spans++ )
-    {
-      unsigned char  coverage = spans->coverage;
-
-
-      if ( coverage )
-      {
-        /* For small-spans it is faster to do it by ourselves than
-         * calling `memset'.  This is mainly due to the cost of the
-         * function call.
-         */
-        if ( spans->len >= 8 )
-          FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len );
-        else
-        {
-          unsigned char*  q = p + spans->x;
-
-
-          switch ( spans->len )
-          {
-          case 7: *q++ = (unsigned char)coverage;
-          case 6: *q++ = (unsigned char)coverage;
-          case 5: *q++ = (unsigned char)coverage;
-          case 4: *q++ = (unsigned char)coverage;
-          case 3: *q++ = (unsigned char)coverage;
-          case 2: *q++ = (unsigned char)coverage;
-          case 1: *q   = (unsigned char)coverage;
-          default:
-            ;
-          }
-        }
-      }
-    }
-  }
-
-
-  static void
   gray_hline( RAS_ARG_ TCoord  x,
                        TCoord  y,
-                       TPos    area,
+                       TArea   area,
                        TCoord  acount )
   {
-    int  coverage;
+    int      coverage;
+    FT_Span  span;
 
 
     /* compute the coverage line's coverage, depending on the    */
@@ -1284,179 +1261,88 @@
         coverage = 255;
     }
 
-    y += (TCoord)ras.min_ey;
-    x += (TCoord)ras.min_ex;
-
-    /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */
-    if ( x >= 32767 )
-      x = 32767;
-
-    /* FT_Span.y is an integer, so limit our coordinates appropriately */
-    if ( y >= FT_INT_MAX )
-      y = FT_INT_MAX;
-
-    if ( coverage )
+    if ( ras.render_span )  /* for FT_RASTER_FLAG_DIRECT only */
     {
-      FT_Span*  span;
-      int       count;
+      span.x        = (short)x;
+      span.len      = (unsigned short)acount;
+      span.coverage = (unsigned char)coverage;
+
+      ras.render_span( y, 1, &span, ras.render_span_data );
+    }
+    else
+    {
+      unsigned char*  q = ras.target.origin - ras.target.pitch * y + x;
+      unsigned char   c = (unsigned char)coverage;
 
 
-      /* see whether we can add this span to the current list */
-      count = ras.num_gray_spans;
-      span  = ras.gray_spans + count - 1;
-      if ( count > 0                          &&
-           ras.span_y == y                    &&
-           (int)span->x + span->len == (int)x &&
-           span->coverage == coverage         )
+      /* For small-spans it is faster to do it by ourselves than
+       * calling `memset'.  This is mainly due to the cost of the
+       * function call.
+       */
+      switch ( acount )
       {
-        span->len = (unsigned short)( span->len + acount );
-        return;
+      case 7: *q++ = c;
+      case 6: *q++ = c;
+      case 5: *q++ = c;
+      case 4: *q++ = c;
+      case 3: *q++ = c;
+      case 2: *q++ = c;
+      case 1: *q   = c;
+      case 0: break;
+      default:
+        FT_MEM_SET( q, c, acount );
       }
-
-      if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS )
-      {
-        if ( ras.render_span && count > 0 )
-          ras.render_span( ras.span_y, count, ras.gray_spans,
-                           ras.render_span_data );
-
-#ifdef FT_DEBUG_LEVEL_TRACE
-
-        if ( count > 0 )
-        {
-          int  n;
-
-
-          FT_TRACE7(( "y = %3d ", ras.span_y ));
-          span = ras.gray_spans;
-          for ( n = 0; n < count; n++, span++ )
-            FT_TRACE7(( "[%d..%d]:%02x ",
-                        span->x, span->x + span->len - 1, span->coverage ));
-          FT_TRACE7(( "\n" ));
-        }
-
-#endif /* FT_DEBUG_LEVEL_TRACE */
-
-        ras.num_gray_spans = 0;
-        ras.span_y         = (int)y;
-
-        span  = ras.gray_spans;
-      }
-      else
-        span++;
-
-      /* add a gray span to the current list */
-      span->x        = (short)x;
-      span->len      = (unsigned short)acount;
-      span->coverage = (unsigned char)coverage;
-
-      ras.num_gray_spans++;
     }
   }
 
 
-#ifdef FT_DEBUG_LEVEL_TRACE
-
-  /* to be called while in the debugger --                                */
-  /* this function causes a compiler warning since it is unused otherwise */
   static void
-  gray_dump_cells( RAS_ARG )
+  gray_sweep( RAS_ARG )
   {
-    int  yindex;
+    int  y;
 
 
-    for ( yindex = 0; yindex < ras.ycount; yindex++ )
-    {
-      PCell  cell;
-
-
-      printf( "%3d:", yindex );
-
-      for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next )
-        printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area );
-      printf( "\n" );
-    }
-  }
-
-#endif /* FT_DEBUG_LEVEL_TRACE */
-
-
-  static void
-  gray_sweep( RAS_ARG_ const FT_Bitmap*  target )
-  {
-    int  yindex;
-
-    FT_UNUSED( target );
-
-
-    if ( ras.num_cells == 0 )
-      return;
-
-    ras.num_gray_spans = 0;
-
     FT_TRACE7(( "gray_sweep: start\n" ));
 
-    for ( yindex = 0; yindex < ras.ycount; yindex++ )
+    for ( y = ras.min_ey; y < ras.max_ey; y++ )
     {
-      PCell   cell  = ras.ycells[yindex];
+      PCell   cell  = ras.ycells[y - ras.min_ey];
       TCoord  cover = 0;
-      TCoord  x     = 0;
+      TCoord  x     = ras.min_ex;
 
 
       for ( ; cell != NULL; cell = cell->next )
       {
-        TPos  area;
+        TArea  area;
 
 
-        if ( cell->x > x && cover != 0 )
-          gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),
+        if ( cover != 0 && cell->x > x )
+          gray_hline( RAS_VAR_ x, y, (TArea)cover * ( ONE_PIXEL * 2 ),
                       cell->x - x );
 
         cover += cell->cover;
-        area   = cover * ( ONE_PIXEL * 2 ) - cell->area;
+        area   = (TArea)cover * ( ONE_PIXEL * 2 ) - cell->area;
 
-        if ( area != 0 && cell->x >= 0 )
-          gray_hline( RAS_VAR_ cell->x, yindex, area, 1 );
+        if ( area != 0 && cell->x >= ras.min_ex )
+          gray_hline( RAS_VAR_ cell->x, y, area, 1 );
 
         x = cell->x + 1;
       }
 
       if ( cover != 0 )
-        gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),
-                    ras.count_ex - x );
-    }
-
-    if ( ras.render_span && ras.num_gray_spans > 0 )
-      ras.render_span( ras.span_y, ras.num_gray_spans,
-                       ras.gray_spans, ras.render_span_data );
-
-#ifdef FT_DEBUG_LEVEL_TRACE
-
-    if ( ras.num_gray_spans > 0 )
-    {
-      FT_Span*  span;
-      int       n;
-
-
-      FT_TRACE7(( "y = %3d ", ras.span_y ));
-      span = ras.gray_spans;
-      for ( n = 0; n < ras.num_gray_spans; n++, span++ )
-        FT_TRACE7(( "[%d..%d]:%02x ",
-                    span->x, span->x + span->len - 1, span->coverage ));
-      FT_TRACE7(( "\n" ));
+        gray_hline( RAS_VAR_ x, y, (TArea)cover * ( ONE_PIXEL * 2 ),
+                    ras.max_ex - x );
     }
 
     FT_TRACE7(( "gray_sweep: end\n" ));
-
-#endif /* FT_DEBUG_LEVEL_TRACE */
-
   }
 
 
-#ifdef _STANDALONE_
+#ifdef STANDALONE_
 
   /*************************************************************************/
   /*                                                                       */
-  /*  The following function should only compile in stand-alone mode,      */
+  /*  The following functions should only compile in stand-alone mode,     */
   /*  i.e., when building this component without the rest of FreeType.     */
   /*                                                                       */
   /*************************************************************************/
@@ -1727,32 +1613,102 @@
     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:
     return FT_THROW( Invalid_Outline );
   }
 
-#endif /* _STANDALONE_ */
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Outline_Get_CBox                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Return an outline's `control box'.  The control box encloses all   */
+  /*    the outline's points, including Bézier control points.  Though it  */
+  /*    coincides with the exact bounding box for most glyphs, it can be   */
+  /*    slightly larger in some situations (like when rotating an outline  */
+  /*    that contains Bézier outside arcs).                                */
+  /*                                                                       */
+  /*    Computing the control box is very fast, while getting the bounding */
+  /*    box can take much more time as it needs to walk over all segments  */
+  /*    and arcs in the outline.  To get the latter, you can use the       */
+  /*    `ftbbox' component, which is dedicated to this single task.        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    outline :: A pointer to the source outline descriptor.             */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    acbox   :: The outline's control box.                              */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    See @FT_Glyph_Get_CBox for a discussion of tricky fonts.           */
+  /*                                                                       */
 
-  typedef struct  gray_TBand_
+  static void
+  FT_Outline_Get_CBox( const FT_Outline*  outline,
+                       FT_BBox           *acbox )
   {
-    TPos  min, max;
+    TPos  xMin, yMin, xMax, yMax;
 
-  } gray_TBand;
+
+    if ( outline && acbox )
+    {
+      if ( outline->n_points == 0 )
+      {
+        xMin = 0;
+        yMin = 0;
+        xMax = 0;
+        yMax = 0;
+      }
+      else
+      {
+        FT_Vector*  vec   = outline->points;
+        FT_Vector*  limit = vec + outline->n_points;
+
+
+        xMin = xMax = vec->x;
+        yMin = yMax = vec->y;
+        vec++;
+
+        for ( ; vec < limit; vec++ )
+        {
+          TPos  x, y;
+
+
+          x = vec->x;
+          if ( x < xMin ) xMin = x;
+          if ( x > xMax ) xMax = x;
+
+          y = vec->y;
+          if ( y < yMin ) yMin = y;
+          if ( y > yMax ) yMax = y;
+        }
+      }
+      acbox->xMin = xMin;
+      acbox->xMax = xMax;
+      acbox->yMin = yMin;
+      acbox->yMax = yMax;
+    }
+  }
+
+#endif /* STANDALONE_ */
 
 
   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
@@ -1771,10 +1727,18 @@
       error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras );
       if ( !ras.invalid )
         gray_record_cell( RAS_VAR );
+
+      FT_TRACE7(( "band [%d..%d]: %d cells\n",
+                  ras.min_ey, ras.max_ey, ras.num_cells ));
     }
     else
+    {
       error = FT_THROW( Memory_Overflow );
 
+      FT_TRACE7(( "band [%d..%d]: to be bisected\n",
+                  ras.min_ey, ras.max_ey ));
+    }
+
     return error;
   }
 
@@ -1782,158 +1746,116 @@
   static int
   gray_convert_glyph( RAS_ARG )
   {
-    gray_TBand            bands[40];
-    gray_TBand* volatile  band;
-    int volatile          n, num_bands;
-    TPos volatile         min, max, max_y;
-    FT_BBox*              clip;
+    TCell    buffer[FT_MAX_GRAY_POOL];
+    TCoord   band_size = FT_MAX_GRAY_POOL / 8;
+    TCoord   count = ras.max_ey - ras.min_ey;
+    int      num_bands;
+    TCoord   min, max, max_y;
+    TCoord   bands[32];  /* enough to accommodate bisections */
+    TCoord*  band;
 
 
-    /* Set up state in the raster object */
-    gray_compute_cbox( RAS_VAR );
-
-    /* clip to target bitmap, exit if nothing to do */
-    clip = &ras.clip_box;
-
-    if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax ||
-         ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax )
-      return 0;
-
-    if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin;
-    if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin;
-
-    if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax;
-    if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax;
-
-    ras.count_ex = ras.max_ex - ras.min_ex;
-    ras.count_ey = ras.max_ey - ras.min_ey;
-
     /* set up vertical bands */
-    num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size );
-    if ( num_bands == 0 )
-      num_bands = 1;
-    if ( num_bands >= 39 )
-      num_bands = 39;
-
-    ras.band_shoot = 0;
+    if ( count > band_size )
+    {
+      /* two divisions rounded up */
+      num_bands = (int)( ( count + band_size - 1) / band_size );
+      band_size = ( count + num_bands - 1 ) / num_bands;
+    }
 
     min   = ras.min_ey;
     max_y = ras.max_ey;
 
-    for ( n = 0; n < num_bands; n++, min = max )
+    for ( ; min < max_y; min = max )
     {
-      max = min + ras.band_size;
-      if ( n == num_bands - 1 || max > max_y )
+      max = min + band_size;
+      if ( max > max_y )
         max = max_y;
 
-      bands[0].min = min;
-      bands[0].max = max;
-      band         = bands;
+      band    = bands;
+      band[1] = min;
+      band[0] = max;
 
       do
       {
-        TPos  bottom, top, middle;
-        int   error;
+        TCoord  width = band[0] - band[1];
+        int     error;
 
+
+        /* memory management */
         {
-          PCell  cells_max;
-          int    yindex;
-          long   cell_start, cell_end, cell_mod;
+          size_t  ycount = (size_t)width;
+          size_t  cell_start;
 
 
-          ras.ycells = (PCell*)ras.buffer;
-          ras.ycount = band->max - band->min;
+          cell_start = ( ycount * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) /
+                       sizeof ( TCell );
 
-          cell_start = (long)sizeof ( PCell ) * ras.ycount;
-          cell_mod   = cell_start % (long)sizeof ( TCell );
-          if ( cell_mod > 0 )
-            cell_start += (long)sizeof ( TCell ) - cell_mod;
+          ras.cells     = buffer + cell_start;
+          ras.max_cells = (FT_PtrDist)( FT_MAX_GRAY_POOL - cell_start );
+          ras.num_cells = 0;
 
-          cell_end  = ras.buffer_size;
-          cell_end -= cell_end % (long)sizeof ( TCell );
-
-          cells_max = (PCell)( (char*)ras.buffer + cell_end );
-          ras.cells = (PCell)( (char*)ras.buffer + cell_start );
-          if ( ras.cells >= cells_max )
-            goto ReduceBands;
-
-          ras.max_cells = cells_max - ras.cells;
-          if ( ras.max_cells < 2 )
-            goto ReduceBands;
-
-          for ( yindex = 0; yindex < ras.ycount; yindex++ )
-            ras.ycells[yindex] = NULL;
+          ras.ycells = (PCell*)buffer;
+          while ( ycount )
+            ras.ycells[--ycount] = NULL;
         }
 
-        ras.num_cells = 0;
         ras.invalid   = 1;
-        ras.min_ey    = band->min;
-        ras.max_ey    = band->max;
-        ras.count_ey  = band->max - band->min;
+        ras.min_ey    = band[1];
+        ras.max_ey    = band[0];
 
         error = gray_convert_glyph_inner( RAS_VAR );
 
         if ( !error )
         {
-          gray_sweep( RAS_VAR_ &ras.target );
+          gray_sweep( RAS_VAR );
           band--;
           continue;
         }
         else if ( error != ErrRaster_Memory_Overflow )
           return 1;
 
-      ReduceBands:
         /* render pool overflow; we will reduce the render band by half */
-        bottom = band->min;
-        top    = band->max;
-        middle = bottom + ( ( top - bottom ) >> 1 );
+        width >>= 1;
 
         /* This is too complex for a single scanline; there must */
         /* be some problems.                                     */
-        if ( middle == bottom )
+        if ( width == 0 )
         {
-#ifdef FT_DEBUG_LEVEL_TRACE
           FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" ));
-#endif
           return 1;
         }
 
-        if ( bottom-top >= ras.band_size )
-          ras.band_shoot++;
-
-        band[1].min = bottom;
-        band[1].max = middle;
-        band[0].min = middle;
-        band[0].max = top;
         band++;
+        band[1]  = band[0];
+        band[0] += width;
       } while ( band >= bands );
     }
 
-    if ( ras.band_shoot > 8 && ras.band_size > 16 )
-      ras.band_size = ras.band_size / 2;
-
     return 0;
   }
 
 
   static int
-  gray_raster_render( gray_PRaster             raster,
+  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
     gray_TWorker  worker[1];
-
-    TCell  buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( TCell )];
-    long   buffer_size = sizeof ( buffer );
-    int    band_size   = (int)( buffer_size /
-                                (long)( sizeof ( TCell ) * 8 ) );
+#endif
 
 
     if ( !raster )
       return FT_THROW( Invalid_Argument );
 
+    /* this version does not support monochrome rendering */
+    if ( !( params->flags & FT_RASTER_FLAG_AA ) )
+      return FT_THROW( Invalid_Mode );
+
     if ( !outline )
       return FT_THROW( Invalid_Outline );
 
@@ -1948,9 +1870,19 @@
            outline->contours[outline->n_contours - 1] + 1 )
       return FT_THROW( Invalid_Outline );
 
-    /* if direct mode is not set, we must have a target bitmap */
-    if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
+    ras.outline = *outline;
+
+    if ( params->flags & FT_RASTER_FLAG_DIRECT )
     {
+      if ( !params->gray_spans )
+        return 0;
+
+      ras.render_span      = (FT_Raster_Span_Func)params->gray_spans;
+      ras.render_span_data = params->user;
+    }
+    else
+    {
+      /* if direct mode is not set, we must have a target bitmap */
       if ( !target_map )
         return FT_THROW( Invalid_Argument );
 
@@ -1960,51 +1892,59 @@
 
       if ( !target_map->buffer )
         return FT_THROW( Invalid_Argument );
+
+      if ( target_map->pitch < 0 )
+        ras.target.origin = target_map->buffer;
+      else
+        ras.target.origin = target_map->buffer
+              + ( target_map->rows - 1 ) * (unsigned int)target_map->pitch;
+
+      ras.target.pitch = target_map->pitch;
+
+      ras.render_span      = (FT_Raster_Span_Func)NULL;
+      ras.render_span_data = NULL;
     }
 
-    /* this version does not support monochrome rendering */
-    if ( !( params->flags & FT_RASTER_FLAG_AA ) )
-      return FT_THROW( Invalid_Mode );
+    FT_Outline_Get_CBox( outline, &cbox );
+
+    /* reject too large outline coordinates */
+    if ( cbox.xMin < -0x1000000L || cbox.xMax > 0x1000000L ||
+         cbox.yMin < -0x1000000L || cbox.yMax > 0x1000000L )
+      return FT_THROW( Invalid_Outline );
+
+    /* truncate the bounding box to integer pixels */
+    cbox.xMin = cbox.xMin >> 6;
+    cbox.yMin = cbox.yMin >> 6;
+    cbox.xMax = ( cbox.xMax + 63 ) >> 6;
+    cbox.yMax = ( cbox.yMax + 63 ) >> 6;
 
     /* compute clipping box */
     if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
     {
       /* compute clip box from target pixmap */
-      ras.clip_box.xMin = 0;
-      ras.clip_box.yMin = 0;
-      ras.clip_box.xMax = (FT_Pos)target_map->width;
-      ras.clip_box.yMax = (FT_Pos)target_map->rows;
+      clip.xMin = 0;
+      clip.yMin = 0;
+      clip.xMax = (FT_Pos)target_map->width;
+      clip.yMax = (FT_Pos)target_map->rows;
     }
     else if ( params->flags & FT_RASTER_FLAG_CLIP )
-      ras.clip_box = params->clip_box;
+      clip = params->clip_box;
     else
     {
-      ras.clip_box.xMin = -32768L;
-      ras.clip_box.yMin = -32768L;
-      ras.clip_box.xMax =  32767L;
-      ras.clip_box.yMax =  32767L;
+      clip.xMin = -32768L;
+      clip.yMin = -32768L;
+      clip.xMax =  32767L;
+      clip.yMax =  32767L;
     }
 
-    gray_init_cells( RAS_VAR_ buffer, buffer_size );
+    /* clip to target bitmap, exit if nothing to do */
+    ras.min_ex = FT_MAX( cbox.xMin, clip.xMin );
+    ras.min_ey = FT_MAX( cbox.yMin, clip.yMin );
+    ras.max_ex = FT_MIN( cbox.xMax, clip.xMax );
+    ras.max_ey = FT_MIN( cbox.yMax, clip.yMax );
 
-    ras.outline        = *outline;
-    ras.num_cells      = 0;
-    ras.invalid        = 1;
-    ras.band_size      = band_size;
-    ras.num_gray_spans = 0;
-    ras.span_y         = 0;
-
-    if ( params->flags & FT_RASTER_FLAG_DIRECT )
-    {
-      ras.render_span      = (FT_Raster_Span_Func)params->gray_spans;
-      ras.render_span_data = params->user;
-    }
-    else
-    {
-      ras.target           = *target_map;
-      ras.render_span      = (FT_Raster_Span_Func)gray_render_span;
-      ras.render_span_data = &ras;
-    }
+    if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey )
+      return 0;
 
     return gray_convert_glyph( RAS_VAR );
   }
@@ -2013,7 +1953,7 @@
   /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/
   /****                         a static object.                   *****/
 
-#ifdef _STANDALONE_
+#ifdef STANDALONE_
 
   static int
   gray_raster_new( void*       memory,
@@ -2025,7 +1965,7 @@
 
 
     *araster = (FT_Raster)&the_raster;
-    FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) );
+    FT_ZERO( &the_raster );
 
     return 0;
   }
@@ -2038,7 +1978,7 @@
     FT_UNUSED( raster );
   }
 
-#else /* !_STANDALONE_ */
+#else /* !STANDALONE_ */
 
   static int
   gray_raster_new( FT_Memory   memory,
@@ -2068,13 +2008,13 @@
     FT_FREE( raster );
   }
 
-#endif /* !_STANDALONE_ */
+#endif /* !STANDALONE_ */
 
 
   static void
-  gray_raster_reset( FT_Raster  raster,
-                     char*      pool_base,
-                     long       pool_size )
+  gray_raster_reset( FT_Raster       raster,
+                     unsigned char*  pool_base,
+                     unsigned long   pool_size )
   {
     FT_UNUSED( raster );
     FT_UNUSED( pool_base );
@@ -2101,11 +2041,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/third_party/freetype/src/smooth/ftgrays.h b/third_party/freetype/src/smooth/ftgrays.h
index 1b57603..a5447da 100644
--- a/third_party/freetype/src/smooth/ftgrays.h
+++ b/third_party/freetype/src/smooth/ftgrays.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType smooth renderer declaration                                 */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,15 +16,15 @@
 /***************************************************************************/
 
 
-#ifndef __FTGRAYS_H__
-#define __FTGRAYS_H__
+#ifndef FTGRAYS_H_
+#define FTGRAYS_H_
 
 #ifdef __cplusplus
   extern "C" {
 #endif
 
 
-#ifdef _STANDALONE_
+#ifdef STANDALONE_
 #include "ftimage.h"
 #else
 #include <ft2build.h>
@@ -52,7 +52,7 @@
   }
 #endif
 
-#endif /* __FTGRAYS_H__ */
+#endif /* FTGRAYS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/smooth/ftsmerrs.h b/third_party/freetype/src/smooth/ftsmerrs.h
index cc38aa1..a528c61 100644
--- a/third_party/freetype/src/smooth/ftsmerrs.h
+++ b/third_party/freetype/src/smooth/ftsmerrs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    smooth renderer error codes (specification only).                    */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -23,12 +23,12 @@
   /*                                                                       */
   /*************************************************************************/
 
-#ifndef __FTSMERRS_H__
-#define __FTSMERRS_H__
+#ifndef FTSMERRS_H_
+#define FTSMERRS_H_
 
 #include FT_MODULE_ERRORS_H
 
-#undef __FTERRORS_H__
+#undef FTERRORS_H_
 
 #undef  FT_ERR_PREFIX
 #define FT_ERR_PREFIX  Smooth_Err_
@@ -36,7 +36,7 @@
 
 #include FT_ERRORS_H
 
-#endif /* __FTSMERRS_H__ */
+#endif /* FTSMERRS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/smooth/ftsmooth.c b/third_party/freetype/src/smooth/ftsmooth.c
index 3620550..c9292df 100644
--- a/third_party/freetype/src/smooth/ftsmooth.c
+++ b/third_party/freetype/src/smooth/ftsmooth.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Anti-aliasing renderer interface (body).                             */
 /*                                                                         */
-/*  Copyright 2000-2015 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/third_party/freetype/src/smooth/ftsmooth.h b/third_party/freetype/src/smooth/ftsmooth.h
index 765018c..929e260 100644
--- a/third_party/freetype/src/smooth/ftsmooth.h
+++ b/third_party/freetype/src/smooth/ftsmooth.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Anti-aliasing renderer interface (specification).                    */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTSMOOTH_H__
-#define __FTSMOOTH_H__
+#ifndef FTSMOOTH_H_
+#define FTSMOOTH_H_
 
 
 #include <ft2build.h>
@@ -43,7 +43,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTSMOOTH_H__ */
+#endif /* FTSMOOTH_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/smooth/ftspic.c b/third_party/freetype/src/smooth/ftspic.c
index 8e6ed57..fb89be3 100644
--- a/third_party/freetype/src/smooth/ftspic.c
+++ b/third_party/freetype/src/smooth/ftspic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for smooth module.   */
 /*                                                                         */
-/*  Copyright 2009-2015 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/third_party/freetype/src/smooth/ftspic.h b/third_party/freetype/src/smooth/ftspic.h
index 071afcf..9ddd1c7 100644
--- a/third_party/freetype/src/smooth/ftspic.h
+++ b/third_party/freetype/src/smooth/ftspic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for smooth module.   */
 /*                                                                         */
-/*  Copyright 2009-2015 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __FTSPIC_H__
-#define __FTSPIC_H__
+#ifndef FTSPIC_H_
+#define FTSPIC_H_
 
 
 #include FT_INTERNAL_PIC_H
@@ -69,7 +69,7 @@
 
 FT_END_HEADER
 
-#endif /* __FTSPIC_H__ */
+#endif /* FTSPIC_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/smooth/smooth.c b/third_party/freetype/src/smooth/smooth.c
index 4ca4344..200f5dc 100644
--- a/third_party/freetype/src/smooth/smooth.c
+++ b/third_party/freetype/src/smooth/smooth.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType anti-aliasing rasterer module component (body only).        */
 /*                                                                         */
-/*  Copyright 1996-2015 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/third_party/freetype/src/truetype/truetype.c b/third_party/freetype/src/truetype/truetype.c
index f929437..4866103 100644
--- a/third_party/freetype/src/truetype/truetype.c
+++ b/third_party/freetype/src/truetype/truetype.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType TrueType driver component (body only).                      */
 /*                                                                         */
-/*  Copyright 1996-2015 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/third_party/freetype/src/truetype/ttdriver.c b/third_party/freetype/src/truetype/ttdriver.c
index 08b30c9..19f7858 100644
--- a/third_party/freetype/src/truetype/ttdriver.c
+++ b/third_party/freetype/src/truetype/ttdriver.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType font driver implementation (body).                          */
 /*                                                                         */
-/*  Copyright 1996-2015 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
@@ -61,23 +62,50 @@
   static FT_Error
   tt_property_set( FT_Module    module,         /* TT_Driver */
                    const char*  property_name,
-                   const void*  value )
+                   const void*  value,
+                   FT_Bool      value_is_string )
   {
     FT_Error   error  = FT_Err_Ok;
     TT_Driver  driver = (TT_Driver)module;
 
+#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+    FT_UNUSED( value_is_string );
+#endif
+
 
     if ( !ft_strcmp( property_name, "interpreter-version" ) )
     {
-      FT_UInt*  interpreter_version = (FT_UInt*)value;
+      FT_UInt  interpreter_version;
 
 
-#ifndef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( *interpreter_version != TT_INTERPRETER_VERSION_35 )
-        error = FT_ERR( Unimplemented_Feature );
+#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+      if ( value_is_string )
+      {
+        const char*  s = (const char*)value;
+
+
+        interpreter_version = (FT_UInt)ft_strtol( s, NULL, 10 );
+      }
       else
 #endif
-        driver->interpreter_version = *interpreter_version;
+      {
+        FT_UInt*  iv = (FT_UInt*)value;
+
+
+        interpreter_version = *iv;
+      }
+
+      if ( interpreter_version == TT_INTERPRETER_VERSION_35
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+           || interpreter_version == TT_INTERPRETER_VERSION_38
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+           || interpreter_version == TT_INTERPRETER_VERSION_40
+#endif
+         )
+        driver->interpreter_version = interpreter_version;
+      else
+        error = FT_ERR( Unimplemented_Feature );
 
       return error;
     }
@@ -117,8 +145,10 @@
 
   FT_DEFINE_SERVICE_PROPERTIESREC(
     tt_service_properties,
-    (FT_Properties_SetFunc)tt_property_set,
-    (FT_Properties_GetFunc)tt_property_get )
+
+    (FT_Properties_SetFunc)tt_property_set,     /* set_property */
+    (FT_Properties_GetFunc)tt_property_get      /* get_property */
+  )
 
 
   /*************************************************************************/
@@ -194,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;
@@ -214,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;
@@ -228,6 +272,7 @@
     return FT_Err_Ok;
   }
 
+
   /*************************************************************************/
   /*************************************************************************/
   /*************************************************************************/
@@ -259,11 +304,11 @@
       /* 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
     {
-      SFNT_Service      sfnt    = (SFNT_Service) ttface->sfnt;
+      SFNT_Service      sfnt    = (SFNT_Service)ttface->sfnt;
       FT_Size_Metrics*  metrics = &size->metrics;
 
 
@@ -291,7 +336,7 @@
     if ( FT_HAS_FIXED_SIZES( size->face ) )
     {
       TT_Face       ttface = (TT_Face)size->face;
-      SFNT_Service  sfnt   = (SFNT_Service) ttface->sfnt;
+      SFNT_Service  sfnt   = (SFNT_Service)ttface->sfnt;
       FT_ULong      strike_index;
 
 
@@ -309,8 +354,27 @@
 
     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
+      /* for the `MPS' bytecode instruction we need the point size */
+      {
+        FT_UInt  resolution = ttsize->metrics.x_ppem > ttsize->metrics.y_ppem
+                                ? req->horiResolution
+                                : req->vertResolution;
+
+
+        /* if we don't have a resolution value, assume 72dpi */
+        if ( req->type == FT_SIZE_REQUEST_TYPE_SCALES ||
+             !resolution                              )
+          resolution = 72;
+
+        ttsize->point_size = FT_MulDiv( ttsize->ttmetrics.ppem,
+                                        64 * 72,
+                                        resolution );
+      }
+#endif
     }
 
     return error;
@@ -415,24 +479,45 @@
   /*************************************************************************/
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
   FT_DEFINE_SERVICE_MULTIMASTERSREC(
     tt_service_gx_multi_masters,
-    (FT_Get_MM_Func)        NULL,
-    (FT_Set_MM_Design_Func) NULL,
-    (FT_Set_MM_Blend_Func)  TT_Set_MM_Blend,
-    (FT_Get_MM_Var_Func)    TT_Get_MM_Var,
-    (FT_Set_Var_Design_Func)TT_Set_Var_Design )
-#endif
+
+    (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 */
+    (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)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) tt_apply_mvar           /* metrics_adjust  */
+  )
+
+#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
+
 
   static const FT_Service_TrueTypeEngineRec  tt_service_truetype_engine =
   {
 #ifdef TT_USE_BYTECODE_INTERPRETER
 
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    FT_TRUETYPE_ENGINE_TYPE_UNPATENTED
-#else
     FT_TRUETYPE_ENGINE_TYPE_PATENTED
-#endif
 
 #else /* !TT_USE_BYTECODE_INTERPRETER */
 
@@ -441,21 +526,28 @@
 #endif /* TT_USE_BYTECODE_INTERPRETER */
   };
 
+
   FT_DEFINE_SERVICE_TTGLYFREC(
     tt_service_truetype_glyf,
-    (TT_Glyf_GetLocationFunc)tt_face_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,
@@ -483,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
@@ -534,31 +626,31 @@
       0x10000L,        /* driver version == 1.0                 */
       0x20000L,        /* driver requires FreeType 2.0 or above */
 
-      (void*)0,        /* driver specific interface */
+      NULL,    /* module-specific interface */
 
-      tt_driver_init,
-      tt_driver_done,
-      tt_get_interface,
+      tt_driver_init,           /* FT_Module_Constructor  module_init   */
+      tt_driver_done,           /* FT_Module_Destructor   module_done   */
+      tt_get_interface,         /* FT_Module_Requester    get_interface */
 
     sizeof ( TT_FaceRec ),
     sizeof ( TT_SizeRec ),
     sizeof ( FT_GlyphSlotRec ),
 
-    tt_face_init,
-    tt_face_done,
-    tt_size_init,
-    tt_size_done,
-    tt_slot_init,
-    0,                       /* FT_Slot_DoneFunc */
+    tt_face_init,               /* FT_Face_InitFunc  init_face */
+    tt_face_done,               /* FT_Face_DoneFunc  done_face */
+    tt_size_init,               /* FT_Size_InitFunc  init_size */
+    tt_size_done,               /* FT_Size_DoneFunc  done_size */
+    tt_slot_init,               /* FT_Slot_InitFunc  init_slot */
+    NULL,                       /* FT_Slot_DoneFunc  done_slot */
 
-    tt_glyph_load,
+    tt_glyph_load,              /* FT_Slot_LoadFunc  load_glyph */
 
-    tt_get_kerning,
-    0,                       /* FT_Face_AttachFunc */
-    tt_get_advances,
+    tt_get_kerning,             /* FT_Face_GetKerningFunc   get_kerning  */
+    NULL,                       /* FT_Face_AttachFunc       attach_file  */
+    tt_get_advances,            /* FT_Face_GetAdvancesFunc  get_advances */
 
-    tt_size_request,
-    TT_SIZE_SELECT
+    tt_size_request,            /* FT_Size_RequestFunc  request_size */
+    TT_SIZE_SELECT              /* FT_Size_SelectFunc   select_size  */
   )
 
 
diff --git a/third_party/freetype/src/truetype/ttdriver.h b/third_party/freetype/src/truetype/ttdriver.h
index 6cacd60..3bcba7f 100644
--- a/third_party/freetype/src/truetype/ttdriver.h
+++ b/third_party/freetype/src/truetype/ttdriver.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level TrueType driver interface (specification).                */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTDRIVER_H__
-#define __TTDRIVER_H__
+#ifndef TTDRIVER_H_
+#define TTDRIVER_H_
 
 
 #include <ft2build.h>
@@ -32,7 +32,7 @@
 
 FT_END_HEADER
 
-#endif /* __TTDRIVER_H__ */
+#endif /* TTDRIVER_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/truetype/tterrors.h b/third_party/freetype/src/truetype/tterrors.h
index ba32cf7..a49f205 100644
--- a/third_party/freetype/src/truetype/tterrors.h
+++ b/third_party/freetype/src/truetype/tterrors.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType error codes (specification only).                           */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -23,12 +23,12 @@
   /*                                                                       */
   /*************************************************************************/
 
-#ifndef __TTERRORS_H__
-#define __TTERRORS_H__
+#ifndef TTERRORS_H_
+#define TTERRORS_H_
 
 #include FT_MODULE_ERRORS_H
 
-#undef __FTERRORS_H__
+#undef FTERRORS_H_
 
 #undef  FT_ERR_PREFIX
 #define FT_ERR_PREFIX  TT_Err_
@@ -36,6 +36,7 @@
 
 #include FT_ERRORS_H
 
-#endif /* __TTERRORS_H__ */
+#endif /* TTERRORS_H_ */
+
 
 /* END */
diff --git a/third_party/freetype/src/truetype/ttgload.c b/third_party/freetype/src/truetype/ttgload.c
index a792ad4..64dc05c 100644
--- a/third_party/freetype/src/truetype/ttgload.c
+++ b/third_party/freetype/src/truetype/ttgload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType Glyph Loader (body).                                        */
 /*                                                                         */
-/*  Copyright 1996-2015 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 FT_TRUETYPE_TAGS_H
 #include FT_OUTLINE_H
 #include FT_TRUETYPE_DRIVER_H
+#include FT_LIST_H
 
 #include "ttgload.h"
 #include "ttpload.h"
@@ -121,7 +122,7 @@
                   FT_UInt    glyph_index )
   {
     TT_Face    face   = loader->face;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
 #endif
 
@@ -152,7 +153,7 @@
     loader->top_bearing  = top_bearing;
     loader->vadvance     = advance_height;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
          loader->exec                                             )
     {
@@ -164,7 +165,7 @@
       /* backwards compatibility mode on and off.                   */
       sph_set_tweaks( loader, glyph_index );
     }
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     if ( !loader->linear_def )
     {
@@ -397,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       */
 
@@ -426,7 +427,8 @@
       load->glyph->control_len  = n_ins;
       load->glyph->control_data = load->exec->glyphIns;
 
-      FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
+      if ( n_ins )
+        FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
     }
 
 #endif /* TT_USE_BYTECODE_INTERPRETER */
@@ -439,7 +441,7 @@
     flag       = (FT_Byte*)outline->tags;
     flag_limit = flag + n_points;
 
-    FT_ASSERT( flag != NULL );
+    FT_ASSERT( flag );
 
     while ( flag < flag_limit )
     {
@@ -659,6 +661,7 @@
     } while ( subglyph->flags & MORE_COMPONENTS );
 
     gloader->current.num_subglyphs = num_subglyphs;
+    FT_TRACE5(( "  %d components\n", num_subglyphs ));
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
 
@@ -730,7 +733,8 @@
   TT_Hint_Glyph( TT_Loader  loader,
                  FT_Bool    is_composite )
   {
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
+    defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     TT_Face    face   = loader->face;
     TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
 #endif
@@ -813,13 +817,23 @@
 
 #endif
 
-    /* save glyph phantom points */
-    loader->pp1 = zone->cur[zone->n_points - 4];
-    loader->pp2 = zone->cur[zone->n_points - 3];
-    loader->pp3 = zone->cur[zone->n_points - 2];
-    loader->pp4 = zone->cur[zone->n_points - 1];
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    /* Save possibly modified glyph phantom points unless in v40 backwards */
+    /* compatibility mode, where no movement on the x axis means no reason */
+    /* to change bearings or advance widths.                               */
+    if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
+            !loader->exec->backwards_compatibility ) )
+    {
+#endif
+      loader->pp1 = zone->cur[zone->n_points - 4];
+      loader->pp2 = zone->cur[zone->n_points - 3];
+      loader->pp3 = zone->cur[zone->n_points - 2];
+      loader->pp4 = zone->cur[zone->n_points - 1];
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    }
+#endif
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
     {
       if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN )
@@ -828,7 +842,7 @@
       else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN )
         FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 );
     }
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     return FT_Err_Ok;
   }
@@ -872,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;
     }
@@ -894,7 +918,7 @@
     }
 
     {
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
       TT_Face    face   = loader->face;
       TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
 
@@ -913,7 +937,7 @@
       FT_Bool  do_scale = FALSE;
 
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
 
       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
       {
@@ -944,7 +968,7 @@
       }
       else
 
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
       {
         /* scale the glyph */
@@ -1075,7 +1099,7 @@
                                             : -subglyph->transform.yx;
         int  c = subglyph->transform.xy > 0 ?  subglyph->transform.xy
                                             : -subglyph->transform.xy;
-        int  d = subglyph->transform.yy > 0 ? subglyph->transform.yy
+        int  d = subglyph->transform.yy > 0 ?  subglyph->transform.yy
                                             : -subglyph->transform.yy;
         int  m = a > b ? a : b;
         int  n = c > d ? c : d;
@@ -1321,49 +1345,71 @@
    * (3) for everything else.
    *
    */
+  static void
+  tt_loader_set_pp( TT_Loader  loader )
+  {
+    FT_Bool  subpixel_hinting = 0;
+    FT_Bool  grayscale        = 0;
+    FT_Bool  use_aw_2         = 0;
+
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+    TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( loader->face );
+#endif
 
-#define TT_LOADER_SET_PP( loader )                                          \
-          do                                                                \
-          {                                                                 \
-            FT_Bool  subpixel_hinting_ = loader->exec                       \
-                                           ? loader->exec->subpixel_hinting \
-                                           : 0;                             \
-            FT_Bool  grayscale_        = loader->exec                       \
-                                           ? loader->exec->grayscale        \
-                                           : 0;                             \
-            FT_Bool  use_aw_2_         = (FT_Bool)( subpixel_hinting_ &&    \
-                                                    grayscale_        );    \
-                                                                            \
-                                                                            \
-            (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \
-            (loader)->pp1.y = 0;                                            \
-            (loader)->pp2.x = (loader)->pp1.x + (loader)->advance;          \
-            (loader)->pp2.y = 0;                                            \
-                                                                            \
-            (loader)->pp3.x = use_aw_2_ ? (loader)->advance / 2 : 0;        \
-            (loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing;  \
-            (loader)->pp4.x = use_aw_2_ ? (loader)->advance / 2 : 0;        \
-            (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance;         \
-          } while ( 0 )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
+    {
+      subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting
+                                      : 0;
+      grayscale        = loader->exec ? loader->exec->grayscale
+                                      : 0;
+    }
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
+    {
+      subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting_lean
+                                      : 0;
+      grayscale        = loader->exec ? loader->exec->grayscale_cleartype
+                                      : 0;
+    }
+#endif
 
-#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+    use_aw_2 = (FT_Bool)( subpixel_hinting && grayscale );
 
-#define TT_LOADER_SET_PP( loader )                                          \
-          do                                                                \
-          {                                                                 \
-            (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \
-            (loader)->pp1.y = 0;                                            \
-            (loader)->pp2.x = (loader)->pp1.x + (loader)->advance;          \
-            (loader)->pp2.y = 0;                                            \
-                                                                            \
-            (loader)->pp3.x = 0;                                            \
-            (loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing;  \
-            (loader)->pp4.x = 0;                                            \
-            (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance;         \
-          } while ( 0 )
+    loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
+    loader->pp1.y = 0;
+    loader->pp2.x = loader->pp1.x + loader->advance;
+    loader->pp2.y = 0;
 
-#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+    loader->pp3.x = use_aw_2 ? loader->advance / 2 : 0;
+    loader->pp3.y = loader->bbox.yMax + loader->top_bearing;
+    loader->pp4.x = use_aw_2 ? loader->advance / 2 : 0;
+    loader->pp4.y = loader->pp3.y - loader->vadvance;
+  }
+
+
+  /* a utility function to retrieve i-th node from given FT_List */
+  static FT_ListNode
+  ft_list_get_node_at( FT_List  list,
+                       FT_UInt  index )
+  {
+    FT_ListNode  cur;
+
+
+    if ( !list )
+      return NULL;
+
+    for ( cur = list->head; cur; cur = cur->next )
+    {
+      if ( !index )
+        return cur;
+
+      index--;
+    }
+
+    return NULL;
+  }
 
 
   /*************************************************************************/
@@ -1395,13 +1441,17 @@
 #endif
 
 
-    /* some fonts have an incorrect value of `maxComponentDepth', */
-    /* thus we allow depth 1 to catch the majority of them        */
-    if ( recurse_count > 1                                   &&
-         recurse_count > face->max_profile.maxComponentDepth )
+#ifdef FT_DEBUG_LEVEL_TRACE
+    if ( recurse_count )
+      FT_TRACE5(( "  nesting level: %d\n", recurse_count ));
+#endif
+
+    /* some fonts have an incorrect value of `maxComponentDepth' */
+    if ( recurse_count > face->max_profile.maxComponentDepth )
     {
-      error = FT_THROW( Invalid_Composite );
-      goto Exit;
+      FT_TRACE1(( "load_truetype_glyph: maxComponentDepth set to %d\n",
+                  recurse_count ));
+      face->max_profile.maxComponentDepth = (FT_UShort)recurse_count;
     }
 
 #ifndef FT_CONFIG_OPTION_INCREMENTAL
@@ -1447,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 );
@@ -1465,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" ));
@@ -1477,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;
@@ -1516,7 +1566,7 @@
 
       /* must initialize points before (possibly) overriding */
       /* glyph metrics from the incremental interface        */
-      TT_LOADER_SET_PP( loader );
+      tt_loader_set_pp( loader );
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
       tt_get_metrics_incr_overrides( loader, glyph_index );
@@ -1524,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'  */
@@ -1567,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 */
@@ -1591,7 +1649,7 @@
 
     /* must initialize phantom points before (possibly) overriding */
     /* glyph metrics from the incremental interface                */
-    TT_LOADER_SET_PP( loader );
+    tt_loader_set_pp( loader );
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
     tt_get_metrics_incr_overrides( loader, glyph_index );
@@ -1627,10 +1685,48 @@
     /* otherwise, load a composite! */
     else if ( loader->n_contours == -1 )
     {
+      FT_Memory  memory = face->root.memory;
+
       FT_UInt   start_point;
       FT_UInt   start_contour;
       FT_ULong  ins_pos;  /* position of composite instructions, if any */
 
+      FT_ListNode  node, node2;
+
+
+      /*
+       * We store the glyph index directly in the `node->data' pointer,
+       * following the glib solution (cf. macro `GUINT_TO_POINTER') with a
+       * double cast to make this portable.  Note, however, that this needs
+       * pointers with a width of at least 32 bits.
+       */
+
+
+      /* clear the nodes filled by sibling chains */
+      node = ft_list_get_node_at( &loader->composites, recurse_count );
+      for ( node2 = node; node2; node2 = node2->next )
+        node2->data = (void*)ULONG_MAX;
+
+      /* check whether we already have a composite glyph with this index */
+      if ( FT_List_Find( &loader->composites,
+                         (void*)(unsigned long)glyph_index ) )
+      {
+        FT_TRACE1(( "TT_Load_Composite_Glyph:"
+                    " infinite recursion detected\n" ));
+        error = FT_THROW( Invalid_Composite );
+        goto Exit;
+      }
+
+      else if ( node )
+        node->data = (void*)(unsigned long)glyph_index;
+
+      else
+      {
+        if ( FT_NEW( node ) )
+          goto Exit;
+        node->data = (void*)(unsigned long)glyph_index;
+        FT_List_Add( &loader->composites, node );
+      }
 
       start_point   = (FT_UInt)gloader->base.outline.n_points;
       start_contour = (FT_UInt)gloader->base.outline.n_contours;
@@ -1649,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;
@@ -1659,8 +1755,6 @@
         char*       tags     = NULL;
         short*      contours = NULL;
 
-        FT_Memory  memory = face->root.memory;
-
 
         limit = (short)gloader->current.num_subglyphs;
 
@@ -1669,6 +1763,10 @@
         outline.n_points   = (short)( gloader->current.num_subglyphs + 4 );
         outline.n_contours = outline.n_points;
 
+        outline.points   = NULL;
+        outline.tags     = NULL;
+        outline.contours = NULL;
+
         if ( FT_NEW_ARRAY( points, outline.n_points )   ||
              FT_NEW_ARRAY( tags, outline.n_points )     ||
              FT_NEW_ARRAY( contours, outline.n_points ) )
@@ -1716,22 +1814,22 @@
 
         /* 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;
 
         for ( i = 0; i < limit; i++, subglyph++ )
         {
-          /* XXX: overflow check for subglyph->{arg1,arg2}.         */
-          /*      Deltas must be within signed 16-bit,              */
-          /*      but the restriction of summed deltas is not clear */
-          subglyph->arg1 = (FT_Int16)points[i].x;
-          subglyph->arg2 = (FT_Int16)points[i].y;
+          if ( subglyph->flags & ARGS_ARE_XY_VALUES )
+          {
+            subglyph->arg1 = (FT_Int16)points[i].x;
+            subglyph->arg2 = (FT_Int16)points[i].y;
+          }
         }
 
         loader->pp1.x = points[i + 0].x;
@@ -1744,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 );
@@ -1803,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 */
@@ -1815,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,
@@ -1834,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;
@@ -1908,7 +2022,8 @@
                          FT_UInt    glyph_index )
   {
     TT_Face    face   = loader->face;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
+    defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
 #endif
 
@@ -1935,11 +2050,18 @@
     glyph->metrics.horiBearingY = bbox.yMax;
     glyph->metrics.horiAdvance  = loader->pp2.x - loader->pp1.x;
 
-    /* adjust advance width to the value contained in the hdmx table */
-    /* unless FT_LOAD_COMPUTE_METRICS is set                         */
-    if ( !face->postscript.isFixedPitch                    &&
-         IS_HINTED( loader->load_flags )                   &&
-         !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) )
+    /* Adjust advance width to the value contained in the hdmx table    */
+    /* unless FT_LOAD_COMPUTE_METRICS is set or backwards compatibility */
+    /* mode of the v40 interpreter is active.  See `ttinterp.h' for     */
+    /* details on backwards compatibility mode.                         */
+    if (
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+         !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
+            ( loader->exec && loader->exec->backwards_compatibility  ) ) &&
+#endif
+         !face->postscript.isFixedPitch                                  &&
+         IS_HINTED( loader->load_flags )                                 &&
+         !( loader->load_flags & FT_LOAD_COMPUTE_METRICS )               )
     {
       FT_Byte*  widthp;
 
@@ -1948,7 +2070,7 @@
                                            size->root.metrics.x_ppem,
                                            glyph_index );
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
 
       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
       {
@@ -1966,7 +2088,7 @@
       }
       else
 
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
       {
         if ( widthp )
@@ -2155,12 +2277,16 @@
 #ifdef TT_USE_BYTECODE_INTERPRETER
     FT_Bool    pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
 #endif
+#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
+    defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)glyph->face );
+#endif
 
 
     face   = (TT_Face)glyph->face;
     stream = face->root.stream;
 
-    FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) );
+    FT_ZERO( loader );
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
 
@@ -2168,11 +2294,13 @@
     if ( IS_HINTED( load_flags ) && !glyf_table_only )
     {
       TT_ExecContext  exec;
-      FT_Bool         grayscale;
+      FT_Bool         grayscale = TRUE;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+      FT_Bool         subpixel_hinting_lean;
+      FT_Bool         grayscale_cleartype;
+#endif
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
-
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
       FT_Bool  subpixel_hinting = FALSE;
 
 #if 0
@@ -2184,7 +2312,7 @@
       FT_Bool  subpixel_positioned;
       FT_Bool  gray_cleartype;
 #endif
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
       FT_Bool  reexecute = FALSE;
 
@@ -2205,7 +2333,26 @@
       if ( !exec )
         return FT_THROW( Could_Not_Find_Context );
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
+      {
+        subpixel_hinting_lean   = TRUE;
+        grayscale_cleartype     = !FT_BOOL( load_flags         &
+                                            FT_LOAD_TARGET_LCD     ||
+                                            load_flags           &
+                                            FT_LOAD_TARGET_LCD_V   );
+        exec->vertical_lcd_lean = FT_BOOL( load_flags           &
+                                           FT_LOAD_TARGET_LCD_V );
+      }
+      else
+      {
+        subpixel_hinting_lean   = FALSE;
+        grayscale_cleartype     = FALSE;
+        exec->vertical_lcd_lean = FALSE;
+      }
+#endif
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
 
       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
       {
@@ -2262,18 +2409,23 @@
       }
       else
 
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
-      {
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
+        grayscale = FT_BOOL( !subpixel_hinting_lean               &&
+                             FT_LOAD_TARGET_MODE( load_flags ) !=
+                               FT_RENDER_MODE_MONO                );
+      else
+#endif
         grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
-                             FT_RENDER_MODE_MONO );
-      }
+                               FT_RENDER_MODE_MONO             );
 
       error = TT_Load_Context( exec, face, size );
       if ( error )
         return error;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
 
       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
       {
@@ -2301,9 +2453,37 @@
       }
       else
 
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
       {
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+        if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
+        {
+          /* a change from mono to subpixel rendering (and vice versa) */
+          /* requires a re-execution of the CVT program                */
+          if ( subpixel_hinting_lean != exec->subpixel_hinting_lean )
+          {
+            FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
+                        " re-executing `prep' table\n" ));
+
+            exec->subpixel_hinting_lean = subpixel_hinting_lean;
+            reexecute                   = TRUE;
+          }
+
+          /* a change from colored to grayscale subpixel rendering (and */
+          /* vice versa) requires a re-execution of the CVT program     */
+          if ( grayscale_cleartype != exec->grayscale_cleartype )
+          {
+            FT_TRACE4(( "tt_loader_init: grayscale subpixel hinting change,"
+                        " re-executing `prep' table\n" ));
+
+            exec->grayscale_cleartype = grayscale_cleartype;
+            reexecute                 = TRUE;
+          }
+        }
+#endif
+
         /* a change from mono to grayscale rendering (and vice versa) */
         /* requires a re-execution of the CVT program                 */
         if ( grayscale != exec->grayscale )
@@ -2336,10 +2516,11 @@
       if ( exec->GS.instruct_control & 2 )
         exec->GS = tt_default_graphics_state;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
       /* check whether we have a font hinted for ClearType --           */
       /* note that this flag can also be modified in a glyph's bytecode */
-      if ( exec->GS.instruct_control & 4 )
+      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
+           exec->GS.instruct_control & 4                            )
         exec->ignore_x_mode = 0;
 #endif
 
@@ -2350,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 )
     {
@@ -2393,10 +2548,23 @@
     loader->glyph  = (FT_GlyphSlot)glyph;
     loader->stream = stream;
 
+    loader->composites.head = NULL;
+    loader->composites.tail = NULL;
+
     return FT_Err_Ok;
   }
 
 
+  static void
+  tt_loader_done( TT_Loader  loader )
+  {
+    FT_List_Finalize( &loader->composites,
+                      NULL,
+                      loader->face->root.memory,
+                      NULL );
+  }
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -2433,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 )
@@ -2453,6 +2625,7 @@
           /* for the bbox we need the header only */
           (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
           (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
+          tt_loader_done( &loader );
           glyph->linearHoriAdvance = loader.linear;
           glyph->linearVertAdvance = loader.vadvance;
 
@@ -2476,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;
@@ -2548,6 +2727,8 @@
       error = compute_glyph_metrics( &loader, glyph_index );
     }
 
+    tt_loader_done( &loader );
+
     /* Set the `high precision' bit flag.                           */
     /* This is _critical_ to get correct output for monochrome      */
     /* TrueType glyphs at all sizes using the bytecode interpreter. */
@@ -2556,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/third_party/freetype/src/truetype/ttgload.h b/third_party/freetype/src/truetype/ttgload.h
index 8e3255e..1dd6c84 100644
--- a/third_party/freetype/src/truetype/ttgload.h
+++ b/third_party/freetype/src/truetype/ttgload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType Glyph Loader (specification).                               */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTGLOAD_H__
-#define __TTGLOAD_H__
+#ifndef TTGLOAD_H_
+#define TTGLOAD_H_
 
 
 #include <ft2build.h>
@@ -56,7 +56,7 @@
 
 FT_END_HEADER
 
-#endif /* __TTGLOAD_H__ */
+#endif /* TTGLOAD_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/truetype/ttinterp.c b/third_party/freetype/src/truetype/ttinterp.c
index ae2a82a..6ea1a80 100644
--- a/third_party/freetype/src/truetype/ttinterp.c
+++ b/third_party/freetype/src/truetype/ttinterp.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType bytecode interpreter (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -26,10 +26,14 @@
 #include FT_TRIGONOMETRY_H
 #include FT_SYSTEM_H
 #include FT_TRUETYPE_DRIVER_H
+#include FT_MULTIPLE_MASTERS_H
 
 #include "ttinterp.h"
 #include "tterrors.h"
 #include "ttsubpix.h"
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+#include "ttgxvar.h"
+#endif
 
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
@@ -45,19 +49,21 @@
 #define FT_COMPONENT  trace_ttinterp
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* In order to detect infinite loops in the code, we set up a counter    */
-  /* within the run loop.  A single stroke of interpretation is now        */
-  /* limited to a maximum number of opcodes defined below.                 */
-  /*                                                                       */
-#define MAX_RUNNABLE_OPCODES  1000000L
+#define NO_SUBPIXEL_HINTING                                                  \
+          ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
+            TT_INTERPRETER_VERSION_35 )
 
-
-#define SUBPIXEL_HINTING                                                     \
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+#define SUBPIXEL_HINTING_INFINALITY                                          \
           ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
             TT_INTERPRETER_VERSION_38 )
+#endif
 
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+#define SUBPIXEL_HINTING_MINIMAL                                             \
+          ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
+            TT_INTERPRETER_VERSION_40 )
+#endif
 
 #define PROJECT( v1, v2 )                                                \
           exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
@@ -74,14 +80,6 @@
 
   /*************************************************************************/
   /*                                                                       */
-  /* Instruction dispatch function, as used by the interpreter.            */
-  /*                                                                       */
-  typedef void  (*TInstruction_Function)( TT_ExecContext  exc,
-                                          FT_Long*        args );
-
-
-  /*************************************************************************/
-  /*                                                                       */
   /* Two simple bounds-checking macros.                                    */
   /*                                                                       */
 #define BOUNDS( x, n )   ( (FT_UInt)(x)  >= (FT_UInt)(n)  )
@@ -94,20 +92,6 @@
 #undef  FAILURE
 #define FAILURE  1
 
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-#define GUESS_VECTOR( V )                                             \
-  do                                                                  \
-  {                                                                   \
-    if ( exc->face->unpatented_hinting )                              \
-    {                                                                 \
-      exc->GS.V.x = (FT_F2Dot14)( exc->GS.both_x_axis ? 0x4000 : 0 ); \
-      exc->GS.V.y = (FT_F2Dot14)( exc->GS.both_x_axis ? 0 : 0x4000 ); \
-    }                                                                 \
-  } while (0)
-#else
-#define GUESS_VECTOR( V )  do { } while (0)
-#endif
-
 
   /*************************************************************************/
   /*                                                                       */
@@ -145,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    */
@@ -309,8 +293,8 @@
     exec->stackSize = 0;
     exec->glyphSize = 0;
 
-    exec->stack     = NULL;
-    exec->glyphIns  = NULL;
+    exec->stack    = NULL;
+    exec->glyphIns = NULL;
 
     exec->face = NULL;
     exec->size = NULL;
@@ -416,6 +400,7 @@
       exec->maxIDefs   = size->max_instruction_defs;
       exec->FDefs      = size->function_defs;
       exec->IDefs      = size->instruction_defs;
+      exec->pointSize  = size->point_size;
       exec->tt_metrics = size->ttmetrics;
       exec->metrics    = size->metrics;
 
@@ -438,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;
     }
@@ -556,10 +541,6 @@
     exec->GS.freeVector = exec->GS.projVector;
     exec->GS.dualVector = exec->GS.projVector;
 
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    exec->GS.both_x_axis = TRUE;
-#endif
-
     exec->GS.round_state = 1;
     exec->GS.loop        = 1;
 
@@ -586,10 +567,6 @@
     { 0x4000, 0 },
     { 0x4000, 0 },
 
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    TRUE,
-#endif
-
     1, 64, 1,
     TRUE, 68, 0, 0, 9, 3,
     0, FALSE, 0, 1, 1, 1
@@ -709,17 +686,17 @@
 
     /*  IUP[0]    */  PACK( 0, 0 ),
     /*  IUP[1]    */  PACK( 0, 0 ),
-    /*  SHP[0]    */  PACK( 0, 0 ),
-    /*  SHP[1]    */  PACK( 0, 0 ),
+    /*  SHP[0]    */  PACK( 0, 0 ), /* loops */
+    /*  SHP[1]    */  PACK( 0, 0 ), /* loops */
     /*  SHC[0]    */  PACK( 1, 0 ),
     /*  SHC[1]    */  PACK( 1, 0 ),
     /*  SHZ[0]    */  PACK( 1, 0 ),
     /*  SHZ[1]    */  PACK( 1, 0 ),
-    /*  SHPIX     */  PACK( 1, 0 ),
-    /*  IP        */  PACK( 0, 0 ),
+    /*  SHPIX     */  PACK( 1, 0 ), /* loops */
+    /*  IP        */  PACK( 0, 0 ), /* loops */
     /*  MSIRP[0]  */  PACK( 2, 0 ),
     /*  MSIRP[1]  */  PACK( 2, 0 ),
-    /*  AlignRP   */  PACK( 0, 0 ),
+    /*  AlignRP   */  PACK( 0, 0 ), /* loops */
     /*  RTDG      */  PACK( 0, 0 ),
     /*  MIAP[0]   */  PACK( 2, 0 ),
     /*  MIAP[1]   */  PACK( 2, 0 ),
@@ -792,7 +769,7 @@
     /*  SANGW     */  PACK( 1, 0 ),
     /*  AA        */  PACK( 1, 0 ),
 
-    /*  FlipPT    */  PACK( 0, 0 ),
+    /*  FlipPT    */  PACK( 0, 0 ), /* loops */
     /*  FlipRgON  */  PACK( 2, 0 ),
     /*  FlipRgOFF */  PACK( 2, 0 ),
     /*  INS_$83   */  PACK( 0, 0 ),
@@ -810,8 +787,8 @@
     /*  INS_$8F   */  PACK( 0, 0 ),
 
     /*  INS_$90  */   PACK( 0, 0 ),
-    /*  INS_$91  */   PACK( 0, 0 ),
-    /*  INS_$92  */   PACK( 0, 0 ),
+    /*  GETVAR   */   PACK( 0, 0 ), /* will be handled specially */
+    /*  GETDATA  */   PACK( 0, 1 ),
     /*  INS_$93  */   PACK( 0, 0 ),
     /*  INS_$94  */   PACK( 0, 0 ),
     /*  INS_$95  */   PACK( 0, 0 ),
@@ -1093,8 +1070,13 @@
     "7 INS_$8F",
 
     "7 INS_$90",
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    "6 GETVAR",
+    "7 GETDATA",
+#else
     "7 INS_$91",
     "7 INS_$92",
+#endif
     "7 INS_$93",
     "7 INS_$94",
     "7 INS_$95",
@@ -1479,34 +1461,22 @@
   {
     if ( !exc->tt_metrics.ratio )
     {
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-      if ( exc->face->unpatented_hinting )
-      {
-        if ( exc->GS.both_x_axis )
-          exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
-        else
-          exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
-      }
+      if ( exc->GS.projVector.y == 0 )
+        exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
+
+      else if ( exc->GS.projVector.x == 0 )
+        exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
+
       else
-#endif
       {
-        if ( exc->GS.projVector.y == 0 )
-          exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
-
-        else if ( exc->GS.projVector.x == 0 )
-          exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
-
-        else
-        {
-          FT_F26Dot6  x, y;
+        FT_F26Dot6  x, y;
 
 
-          x = TT_MulFix14( exc->tt_metrics.x_ratio,
-                           exc->GS.projVector.x );
-          y = TT_MulFix14( exc->tt_metrics.y_ratio,
-                           exc->GS.projVector.y );
-          exc->tt_metrics.ratio = FT_Hypot( x, y );
-        }
+        x = TT_MulFix14( exc->tt_metrics.x_ratio,
+                         exc->GS.projVector.x );
+        y = TT_MulFix14( exc->tt_metrics.y_ratio,
+                         exc->GS.projVector.y );
+        exc->tt_metrics.ratio = FT_Hypot( x, y );
       }
     }
     return exc->tt_metrics.ratio;
@@ -1604,7 +1574,7 @@
   static FT_Short
   GetShortIns( TT_ExecContext  exc )
   {
-    /* Reading a byte stream so there is no endianess (DaveP) */
+    /* Reading a byte stream so there is no endianness (DaveP) */
     exc->IP += 2;
     return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) +
                          exc->code[exc->IP - 1]      );
@@ -1643,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;
@@ -1685,6 +1655,10 @@
   /* <InOut>                                                               */
   /*    zone     :: The affected glyph zone.                               */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    See `ttinterp.h' for details on backwards compatibility mode.      */
+  /*    `Touches' the point.                                               */
+  /*                                                                       */
   static void
   Direct_Move( TT_ExecContext  exc,
                TT_GlyphZone    zone,
@@ -1694,19 +1668,28 @@
     FT_F26Dot6  v;
 
 
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    FT_ASSERT( !exc->face->unpatented_hinting );
-#endif
-
     v = exc->GS.freeVector.x;
 
     if ( v != 0 )
     {
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( !SUBPIXEL_HINTING                                      ||
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+      if ( SUBPIXEL_HINTING_INFINALITY                            &&
            ( !exc->ignore_x_mode                                ||
              ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+        zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
+      else
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+      /* Exception to the post-IUP curfew: Allow the x component of */
+      /* diagonal moves, but only post-IUP.  DejaVu tries to adjust */
+      /* diagonal stems like on `Z' and `z' post-IUP.               */
+      if ( SUBPIXEL_HINTING_MINIMAL && !exc->backwards_compatibility )
+        zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
+      else
+#endif
+
+      if ( NO_SUBPIXEL_HINTING )
         zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
 
       zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
@@ -1716,7 +1699,13 @@
 
     if ( v != 0 )
     {
-      zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+      if ( !( SUBPIXEL_HINTING_MINIMAL     &&
+              exc->backwards_compatibility &&
+              exc->iupx_called             &&
+              exc->iupy_called             ) )
+#endif
+        zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
 
       zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
     }
@@ -1749,10 +1738,6 @@
     FT_F26Dot6  v;
 
 
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    FT_ASSERT( !exc->face->unpatented_hinting );
-#endif
-
     v = exc->GS.freeVector.x;
 
     if ( v != 0 )
@@ -1771,6 +1756,7 @@
   /*                                                                       */
   /*   The following versions are used whenever both vectors are both      */
   /*   along one of the coordinate unit vectors, i.e. in 90% of the cases. */
+  /*   See `ttinterp.h' for details on backwards compatibility mode.       */
   /*                                                                       */
   /*************************************************************************/
 
@@ -1781,12 +1767,19 @@
                  FT_UShort       point,
                  FT_F26Dot6      distance )
   {
-    FT_UNUSED( exc );
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    if ( SUBPIXEL_HINTING_INFINALITY && !exc->ignore_x_mode )
+      zone->cur[point].x += distance;
+    else
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( !SUBPIXEL_HINTING   ||
-         !exc->ignore_x_mode )
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    if ( SUBPIXEL_HINTING_MINIMAL && !exc->backwards_compatibility )
+      zone->cur[point].x += distance;
+    else
+#endif
+
+    if ( NO_SUBPIXEL_HINTING )
       zone->cur[point].x += distance;
 
     zone->tags[point]  |= FT_CURVE_TAG_TOUCH_X;
@@ -1801,8 +1794,14 @@
   {
     FT_UNUSED( exc );
 
-    zone->cur[point].y += distance;
-    zone->tags[point]  |= FT_CURVE_TAG_TOUCH_Y;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    if ( !( SUBPIXEL_HINTING_MINIMAL             &&
+            exc->backwards_compatibility         &&
+            exc->iupx_called && exc->iupy_called ) )
+#endif
+      zone->cur[point].y += distance;
+
+    zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
   }
 
 
@@ -2081,7 +2080,7 @@
                         FT_F26Dot6      distance,
                         FT_F26Dot6      compensation )
   {
-    FT_F26Dot6 val;
+    FT_F26Dot6  val;
 
     FT_UNUSED( exc );
 
@@ -2120,7 +2119,7 @@
   /*    Rounded distance.                                                  */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    The TrueType specification says very few about the relationship    */
+  /*    The TrueType specification says very little about the relationship */
   /*    between rounding and engine compensation.  However, it seems from  */
   /*    the description of super round that we should add the compensation */
   /*    before rounding.                                                   */
@@ -2345,10 +2344,6 @@
            FT_Pos          dx,
            FT_Pos          dy )
   {
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    FT_ASSERT( !exc->face->unpatented_hinting );
-#endif
-
     return TT_DotFix14( dx, dy,
                         exc->GS.projVector.x,
                         exc->GS.projVector.y );
@@ -2450,51 +2445,6 @@
   static void
   Compute_Funcs( TT_ExecContext  exc )
   {
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    if ( exc->face->unpatented_hinting )
-    {
-      /* If both vectors point rightwards along the x axis, set          */
-      /* `both-x-axis' true, otherwise set it false.  The x values only  */
-      /* need be tested because the vector has been normalised to a unit */
-      /* vector of length 0x4000 = unity.                                */
-      exc->GS.both_x_axis = (FT_Bool)( exc->GS.projVector.x == 0x4000 &&
-                                       exc->GS.freeVector.x == 0x4000 );
-
-      /* Throw away projection and freedom vector information */
-      /* because the patents don't allow them to be stored.   */
-      /* The relevant US Patents are 5155805 and 5325479.     */
-      exc->GS.projVector.x = 0;
-      exc->GS.projVector.y = 0;
-      exc->GS.freeVector.x = 0;
-      exc->GS.freeVector.y = 0;
-
-      if ( exc->GS.both_x_axis )
-      {
-        exc->func_project   = Project_x;
-        exc->func_move      = Direct_Move_X;
-        exc->func_move_orig = Direct_Move_Orig_X;
-      }
-      else
-      {
-        exc->func_project   = Project_y;
-        exc->func_move      = Direct_Move_Y;
-        exc->func_move_orig = Direct_Move_Orig_Y;
-      }
-
-      if ( exc->GS.dualVector.x == 0x4000 )
-        exc->func_dualproj = Project_x;
-      else if ( exc->GS.dualVector.y == 0x4000 )
-        exc->func_dualproj = Project_y;
-      else
-        exc->func_dualproj = Dual_Project;
-
-      /* Force recalculation of cached aspect ratio */
-      exc->tt_metrics.ratio = 0;
-
-      return;
-    }
-#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */
-
     if ( exc->GS.freeVector.x == 0x4000 )
       exc->F_dot_P = exc->GS.projVector.x;
     else if ( exc->GS.freeVector.y == 0x4000 )
@@ -2634,13 +2584,20 @@
   Ins_MPS( TT_ExecContext  exc,
            FT_Long*        args )
   {
-    /* Note: The point size should be irrelevant in a given font program; */
-    /*       we thus decide to return only the PPEM value.                */
-#if 0
-    args[0] = exc->metrics.pointSize;
-#else
-    args[0] = exc->func_cur_ppem( exc );
-#endif
+    if ( NO_SUBPIXEL_HINTING )
+    {
+      /* Microsoft's GDI bytecode interpreter always returns value 12; */
+      /* we return the current PPEM value instead.                     */
+      args[0] = exc->func_cur_ppem( exc );
+    }
+    else
+    {
+      /* A possible practical application of the MPS instruction is to   */
+      /* implement optical scaling and similar features, which should be */
+      /* based on perceptual attributes, thus independent of the         */
+      /* resolution.                                                     */
+      args[0] = exc->pointSize;
+    }
   }
 
 
@@ -2933,7 +2890,7 @@
   /*                                                                       */
   /* NEG[]:        NEGate                                                  */
   /* Opcode range: 0x65                                                    */
-  /* Stack: f26.6 --> f26.6                                                */
+  /* Stack:        f26.6 --> f26.6                                         */
   /*                                                                       */
   static void
   Ins_NEG( FT_Long*  args )
@@ -2978,8 +2935,6 @@
   Ins_RS( TT_ExecContext  exc,
           FT_Long*        args )
   {
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-
     FT_ULong  I = (FT_ULong)args[0];
 
 
@@ -2992,9 +2947,10 @@
     }
     else
     {
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
       /* subpixel hinting - avoid Typeman Dstroke and */
       /* IStroke and Vacuform rounds                  */
-      if ( SUBPIXEL_HINTING                            &&
+      if ( SUBPIXEL_HINTING_INFINALITY                 &&
            exc->ignore_x_mode                          &&
            ( ( I == 24                             &&
                ( exc->face->sph_found_func_flags &
@@ -3009,25 +2965,9 @@
                exc->iup_called                     ) ) )
         args[0] = 0;
       else
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
         args[0] = exc->storage[I];
     }
-
-#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-    FT_ULong  I = (FT_ULong)args[0];
-
-
-    if ( BOUNDSL( I, exc->storeSize ) )
-    {
-      if ( exc->pedantic_hinting )
-        ARRAY_BOUND_ERROR;
-      else
-        args[0] = 0;
-    }
-    else
-      args[0] = exc->storage[I];
-
-#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
   }
 
 
@@ -3190,7 +3130,7 @@
   /*************************************************************************/
   /*                                                                       */
   /* MAX[]:        MAXimum                                                 */
-  /* Opcode range: 0x68                                                    */
+  /* Opcode range: 0x8B                                                    */
   /* Stack:        int32? int32? --> int32                                 */
   /*                                                                       */
   static void
@@ -3204,7 +3144,7 @@
   /*************************************************************************/
   /*                                                                       */
   /* MIN[]:        MINimum                                                 */
-  /* Opcode range: 0x69                                                    */
+  /* Opcode range: 0x8C                                                    */
   /* Stack:        int32? int32? --> int32                                 */
   /*                                                                       */
   static void
@@ -3448,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 );
+    }
   }
 
 
@@ -3509,7 +3463,7 @@
     TT_DefRecord*  rec;
     TT_DefRecord*  limit;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     /* arguments to opcodes are skipped by `SKIP_Code' */
     FT_Byte    opcode_pattern[9][12] = {
                  /* #0 inline delta function 1 */
@@ -3607,7 +3561,7 @@
     FT_UShort  opcode_pointer[9] = {  0, 0, 0, 0, 0, 0, 0, 0, 0 };
     FT_UShort  opcode_size[9]    = { 12, 8, 8, 6, 7, 4, 5, 4, 2 };
     FT_UShort  i;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
 
     /* some font programs are broken enough to redefine functions! */
@@ -3652,7 +3606,7 @@
     if ( n > exc->maxFunc )
       exc->maxFunc = (FT_UInt16)n;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     /* We don't know for sure these are typeman functions, */
     /* however they are only active when RS 22 is called   */
     if ( n >= 64 && n <= 66 )
@@ -3665,9 +3619,9 @@
     while ( SkipCode( exc ) == SUCCESS )
     {
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
 
-      if ( SUBPIXEL_HINTING )
+      if ( SUBPIXEL_HINTING_INFINALITY )
       {
         for ( i = 0; i < opcode_patterns; i++ )
         {
@@ -3774,7 +3728,7 @@
             ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
       }
 
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
       switch ( exc->opcode )
       {
@@ -3803,9 +3757,9 @@
     TT_CallRec*  pRec;
 
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     exc->sph_in_func_flags = 0x0000;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     if ( exc->callTop <= 0 )     /* We encountered an ENDF without a call */
     {
@@ -3891,8 +3845,8 @@
     if ( !def->active )
       goto Fail;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                               &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    if ( SUBPIXEL_HINTING_INFINALITY                                    &&
          exc->ignore_x_mode                                             &&
          ( ( exc->iup_called                                        &&
              ( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
@@ -3900,7 +3854,7 @@
       goto Fail;
     else
       exc->sph_in_func_flags = def->sph_fdef_flags;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     /* check the call stack */
     if ( exc->callTop >= exc->callSize )
@@ -3979,14 +3933,14 @@
     if ( !def->active )
       goto Fail;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                    &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    if ( SUBPIXEL_HINTING_INFINALITY                         &&
          exc->ignore_x_mode                                  &&
          ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
       goto Fail;
     else
       exc->sph_in_func_flags = def->sph_fdef_flags;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     /* check stack */
     if ( exc->callTop >= exc->callSize )
@@ -4009,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;
@@ -4079,6 +4037,7 @@
         exc->error = FT_THROW( Nested_DEFS );
         return;
       case 0x2D:   /* ENDF */
+        def->end = exc->IP;
         return;
       }
     }
@@ -4298,16 +4257,12 @@
       exc->GS.dualVector.x = AA;
       exc->GS.dualVector.y = BB;
     }
-    else
-      GUESS_VECTOR( projVector );
 
     if ( ( opcode & 2 ) == 0 )
     {
       exc->GS.freeVector.x = AA;
       exc->GS.freeVector.y = BB;
     }
-    else
-      GUESS_VECTOR( freeVector );
 
     Compute_Funcs( exc );
   }
@@ -4329,7 +4284,6 @@
                     &exc->GS.projVector ) == SUCCESS )
     {
       exc->GS.dualVector = exc->GS.projVector;
-      GUESS_VECTOR( freeVector );
       Compute_Funcs( exc );
     }
   }
@@ -4350,7 +4304,6 @@
                     (FT_UShort)args[0],
                     &exc->GS.freeVector ) == SUCCESS )
     {
-      GUESS_VECTOR( projVector );
       Compute_Funcs( exc );
     }
   }
@@ -4365,7 +4318,6 @@
   static void
   Ins_SFVTPV( TT_ExecContext  exc )
   {
-    GUESS_VECTOR( projVector );
     exc->GS.freeVector = exc->GS.projVector;
     Compute_Funcs( exc );
   }
@@ -4394,7 +4346,6 @@
     Normalize( X, Y, &exc->GS.projVector );
 
     exc->GS.dualVector = exc->GS.projVector;
-    GUESS_VECTOR( freeVector );
     Compute_Funcs( exc );
   }
 
@@ -4420,7 +4371,6 @@
     X = S;
 
     Normalize( X, Y, &exc->GS.freeVector );
-    GUESS_VECTOR( projVector );
     Compute_Funcs( exc );
   }
 
@@ -4435,21 +4385,8 @@
   Ins_GPV( TT_ExecContext  exc,
            FT_Long*        args )
   {
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    if ( exc->face->unpatented_hinting )
-    {
-      args[0] = exc->GS.both_x_axis ? 0x4000 : 0;
-      args[1] = exc->GS.both_x_axis ? 0 : 0x4000;
-    }
-    else
-    {
-      args[0] = exc->GS.projVector.x;
-      args[1] = exc->GS.projVector.y;
-    }
-#else
     args[0] = exc->GS.projVector.x;
     args[1] = exc->GS.projVector.y;
-#endif
   }
 
 
@@ -4463,21 +4400,8 @@
   Ins_GFV( TT_ExecContext  exc,
            FT_Long*        args )
   {
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    if ( exc->face->unpatented_hinting )
-    {
-      args[0] = exc->GS.both_x_axis ? 0x4000 : 0;
-      args[1] = exc->GS.both_x_axis ? 0 : 0x4000;
-    }
-    else
-    {
-      args[0] = exc->GS.freeVector.x;
-      args[1] = exc->GS.freeVector.y;
-    }
-#else
     args[0] = exc->GS.freeVector.x;
     args[1] = exc->GS.freeVector.y;
-#endif
   }
 
 
@@ -4597,7 +4521,7 @@
   /*                                                                       */
   /* FLIPOFF[]:    Set auto-FLIP to OFF                                    */
   /* Opcode range: 0x4E                                                    */
-  /* Stack: -->                                                            */
+  /* Stack:        -->                                                     */
   /*                                                                       */
   static void
   Ins_FLIPOFF( TT_ExecContext  exc )
@@ -4916,13 +4840,13 @@
       }
     }
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
-    if ( SUBPIXEL_HINTING   &&
-         exc->ignore_x_mode &&
-         FT_ABS( D ) == 64  )
+    if ( SUBPIXEL_HINTING_INFINALITY &&
+         exc->ignore_x_mode          &&
+         FT_ABS( D ) == 64           )
       D += 1;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     args[0] = D;
   }
@@ -5007,7 +4931,6 @@
     }
 
     Normalize( A, B, &exc->GS.projVector );
-    GUESS_VECTOR( freeVector );
     Compute_Funcs( exc );
   }
 
@@ -5179,12 +5102,23 @@
     exc->GS.instruct_control &= ~(FT_Byte)Kf;
     exc->GS.instruct_control |= (FT_Byte)L;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    /* INSTCTRL modifying flag 3 also has an effect */
-    /* outside of the CVT program                   */
     if ( K == 3 )
-      exc->ignore_x_mode = FT_BOOL( L == 4 );
+    {
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+      /* INSTCTRL modifying flag 3 also has an effect */
+      /* outside of the CVT program                   */
+      if ( SUBPIXEL_HINTING_INFINALITY )
+        exc->ignore_x_mode = FT_BOOL( L == 4 );
 #endif
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+      /* Native ClearType fonts sign a waiver that turns off all backwards */
+      /* compatibility hacks and lets them program points to the grid like */
+      /* it's 1996.  They might sign a waiver for just one glyph, though.  */
+      if ( SUBPIXEL_HINTING_MINIMAL )
+        exc->backwards_compatibility = !FT_BOOL( L == 4 );
+#endif
+    }
   }
 
 
@@ -5239,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;
   }
 
 
@@ -5269,6 +5203,15 @@
     FT_UShort  point;
 
 
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    /* See `ttinterp.h' for details on backwards compatibility mode. */
+    if ( SUBPIXEL_HINTING_MINIMAL     &&
+         exc->backwards_compatibility &&
+         exc->iupx_called             &&
+         exc->iupy_called             )
+      goto Fail;
+#endif
+
     if ( exc->top < exc->GS.loop )
     {
       if ( exc->pedantic_hinting )
@@ -5315,6 +5258,15 @@
     FT_UShort  I, K, L;
 
 
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    /* See `ttinterp.h' for details on backwards compatibility mode. */
+    if ( SUBPIXEL_HINTING_MINIMAL     &&
+         exc->backwards_compatibility &&
+         exc->iupx_called             &&
+         exc->iupy_called             )
+      return;
+#endif
+
     K = (FT_UShort)args[1];
     L = (FT_UShort)args[0];
 
@@ -5344,6 +5296,15 @@
     FT_UShort  I, K, L;
 
 
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    /* See `ttinterp.h' for details on backwards compatibility mode. */
+    if ( SUBPIXEL_HINTING_MINIMAL     &&
+         exc->backwards_compatibility &&
+         exc->iupx_called             &&
+         exc->iupy_called             )
+      return;
+#endif
+
     K = (FT_UShort)args[1];
     L = (FT_UShort)args[0];
 
@@ -5396,31 +5357,14 @@
 
     d = PROJECT( zp.cur + p, zp.org + p );
 
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    if ( exc->face->unpatented_hinting )
-    {
-      if ( exc->GS.both_x_axis )
-      {
-        *x = d;
-        *y = 0;
-      }
-      else
-      {
-        *x = 0;
-        *y = d;
-      }
-    }
-    else
-#endif
-    {
-      *x = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.x, exc->F_dot_P );
-      *y = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.y, exc->F_dot_P );
-    }
+    *x = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.x, exc->F_dot_P );
+    *y = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.y, exc->F_dot_P );
 
     return SUCCESS;
   }
 
 
+  /* See `ttinterp.h' for details on backwards compatibility mode. */
   static void
   Move_Zp2_Point( TT_ExecContext  exc,
                   FT_UShort       point,
@@ -5428,35 +5372,28 @@
                   FT_F26Dot6      dy,
                   FT_Bool         touch )
   {
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    if ( exc->face->unpatented_hinting )
-    {
-      if ( exc->GS.both_x_axis )
-      {
-        exc->zp2.cur[point].x += dx;
-        if ( touch )
-          exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
-      }
-      else
-      {
-        exc->zp2.cur[point].y += dy;
-        if ( touch )
-          exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
-      }
-      return;
-    }
-#endif
-
     if ( exc->GS.freeVector.x != 0 )
     {
-      exc->zp2.cur[point].x += dx;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+      if ( !( SUBPIXEL_HINTING_MINIMAL     &&
+              exc->backwards_compatibility ) )
+#endif
+        exc->zp2.cur[point].x += dx;
+
       if ( touch )
         exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
     }
 
     if ( exc->GS.freeVector.y != 0 )
     {
-      exc->zp2.cur[point].y += dy;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+      if ( !( SUBPIXEL_HINTING_MINIMAL     &&
+              exc->backwards_compatibility &&
+              exc->iupx_called             &&
+              exc->iupy_called             ) )
+#endif
+        exc->zp2.cur[point].y += dy;
+
       if ( touch )
         exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
     }
@@ -5503,13 +5440,12 @@
         }
       }
       else
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
       /* doesn't follow Cleartype spec but produces better result */
-      if ( SUBPIXEL_HINTING   &&
-           exc->ignore_x_mode )
+      if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode )
         Move_Zp2_Point( exc, point, 0, dy, TRUE );
       else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
         Move_Zp2_Point( exc, point, dx, dy, TRUE );
 
       exc->GS.loop--;
@@ -5637,9 +5573,15 @@
   {
     FT_F26Dot6  dx, dy;
     FT_UShort   point;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     FT_Int      B1, B2;
 #endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    FT_Bool     in_twilight = FT_BOOL( exc->GS.gep0 == 0 ||
+                                       exc->GS.gep1 == 0 ||
+                                       exc->GS.gep2 == 0 );
+#endif
+
 
 
     if ( exc->top < exc->GS.loop + 1 )
@@ -5649,26 +5591,8 @@
       goto Fail;
     }
 
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    if ( exc->face->unpatented_hinting )
-    {
-      if ( exc->GS.both_x_axis )
-      {
-        dx = (FT_UInt32)args[0];
-        dy = 0;
-      }
-      else
-      {
-        dx = 0;
-        dy = (FT_UInt32)args[0];
-      }
-    }
-    else
-#endif
-    {
-      dx = TT_MulFix14( args[0], exc->GS.freeVector.x );
-      dy = TT_MulFix14( args[0], exc->GS.freeVector.y );
-    }
+    dx = TT_MulFix14( args[0], exc->GS.freeVector.x );
+    dy = TT_MulFix14( args[0], exc->GS.freeVector.y );
 
     while ( exc->GS.loop > 0 )
     {
@@ -5685,7 +5609,8 @@
         }
       }
       else
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+      if ( SUBPIXEL_HINTING_INFINALITY )
       {
         /*  If not using ignore_x_mode rendering, allow ZP2 move.        */
         /*  If inline deltas aren't allowed, skip ZP2 move.              */
@@ -5695,8 +5620,7 @@
         /*   - the glyph is specifically set to allow SHPIX moves        */
         /*   - the move is on a previously Y-touched point               */
 
-        if ( SUBPIXEL_HINTING   &&
-             exc->ignore_x_mode )
+        if ( exc->ignore_x_mode )
         {
           /* save point for later comparison */
           if ( exc->GS.freeVector.y != 0 )
@@ -5760,15 +5684,30 @@
         else
           Move_Zp2_Point( exc, point, dx, dy, TRUE );
       }
+      else
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+      if ( SUBPIXEL_HINTING_MINIMAL     &&
+           exc->backwards_compatibility )
+      {
+        /* 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.                                                          */
+        if ( in_twilight                                                ||
+             ( !( exc->iupx_called && exc->iupy_called )              &&
+               ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
+                 ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y )    ) ) )
+          Move_Zp2_Point( exc, point, 0, dy, TRUE );
+      }
+      else
+#endif
+        Move_Zp2_Point( exc, point, dx, dy, TRUE );
 
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     Skip:
-
-#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-      Move_Zp2_Point( exc, point, dx, dy, TRUE );
-
-#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
+#endif
       exc->GS.loop--;
     }
 
@@ -5788,14 +5727,13 @@
   Ins_MSIRP( TT_ExecContext  exc,
              FT_Long*        args )
   {
-    FT_UShort   point;
+    FT_UShort   point = 0;
     FT_F26Dot6  distance;
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    FT_F26Dot6  control_value_cutin = 0; /* pacify compiler */
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    FT_F26Dot6  control_value_cutin = 0;
 
 
-    if ( SUBPIXEL_HINTING )
+    if ( SUBPIXEL_HINTING_INFINALITY )
     {
       control_value_cutin = exc->GS.control_value_cutin;
 
@@ -5804,8 +5742,7 @@
            !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
         control_value_cutin = 0;
     }
-
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     point = (FT_UShort)args[0];
 
@@ -5828,14 +5765,14 @@
 
     distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     /* subpixel hinting - make MSIRP respect CVT cut-in; */
-    if ( SUBPIXEL_HINTING                                    &&
+    if ( SUBPIXEL_HINTING_INFINALITY                         &&
          exc->ignore_x_mode                                  &&
          exc->GS.freeVector.x != 0                           &&
          FT_ABS( distance - args[1] ) >= control_value_cutin )
       distance = args[1];
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     exc->func_move( exc, &exc->zp1, point, args[1] - distance );
 
@@ -5874,10 +5811,10 @@
     if ( ( exc->opcode & 1 ) != 0 )
     {
       cur_dist = FAST_PROJECT( &exc->zp0.cur[point] );
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( SUBPIXEL_HINTING          &&
-           exc->ignore_x_mode        &&
-           exc->GS.freeVector.x != 0 )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+      if ( SUBPIXEL_HINTING_INFINALITY &&
+           exc->ignore_x_mode          &&
+           exc->GS.freeVector.x != 0   )
         distance = Round_None(
                      exc,
                      cur_dist,
@@ -5920,14 +5857,14 @@
     cvtEntry            = (FT_ULong)args[1];
     point               = (FT_UShort)args[0];
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                   &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    if ( SUBPIXEL_HINTING_INFINALITY                        &&
          exc->ignore_x_mode                                 &&
          exc->GS.freeVector.x != 0                          &&
          exc->GS.freeVector.y == 0                          &&
          !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
       control_value_cutin = 0;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     if ( BOUNDS( point,     exc->zp0.n_points ) ||
          BOUNDSL( cvtEntry, exc->cvtSize )      )
@@ -5961,27 +5898,27 @@
 
     if ( exc->GS.gep0 == 0 )   /* If in twilight zone */
     {
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
       /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */
       /* Determined via experimentation and may be incorrect...         */
-      if ( !SUBPIXEL_HINTING                      ||
-           ( !exc->ignore_x_mode                ||
-             !exc->face->sph_compatibility_mode ) )
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+      if ( !( SUBPIXEL_HINTING_INFINALITY           &&
+              ( exc->ignore_x_mode                &&
+                exc->face->sph_compatibility_mode ) ) )
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
         exc->zp0.org[point].x = TT_MulFix14( distance,
                                              exc->GS.freeVector.x );
       exc->zp0.org[point].y = TT_MulFix14( distance,
                                            exc->GS.freeVector.y ),
       exc->zp0.cur[point]   = exc->zp0.org[point];
     }
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                               &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    if ( SUBPIXEL_HINTING_INFINALITY                    &&
          exc->ignore_x_mode                             &&
          ( exc->sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
          distance > 0                                   &&
          exc->GS.freeVector.y != 0                      )
       distance = 0;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     org_dist = FAST_PROJECT( &exc->zp0.cur[point] );
 
@@ -5990,10 +5927,10 @@
       if ( FT_ABS( distance - org_dist ) > control_value_cutin )
         distance = org_dist;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( SUBPIXEL_HINTING          &&
-           exc->ignore_x_mode        &&
-           exc->GS.freeVector.x != 0 )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+      if ( SUBPIXEL_HINTING_INFINALITY &&
+           exc->ignore_x_mode          &&
+           exc->GS.freeVector.x != 0   )
         distance = Round_None( exc,
                                distance,
                                exc->tt_metrics.compensations[0] );
@@ -6022,19 +5959,19 @@
   Ins_MDRP( TT_ExecContext  exc,
             FT_Long*        args )
   {
-    FT_UShort   point;
+    FT_UShort   point = 0;
     FT_F26Dot6  org_dist, distance, minimum_distance;
 
 
     minimum_distance = exc->GS.minimum_distance;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                   &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    if ( SUBPIXEL_HINTING_INFINALITY                        &&
          exc->ignore_x_mode                                 &&
          exc->GS.freeVector.x != 0                          &&
          !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
       minimum_distance = 0;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     point = (FT_UShort)args[0];
 
@@ -6098,10 +6035,10 @@
 
     if ( ( exc->opcode & 4 ) != 0 )
     {
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( SUBPIXEL_HINTING          &&
-           exc->ignore_x_mode        &&
-           exc->GS.freeVector.x != 0 )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+      if ( SUBPIXEL_HINTING_INFINALITY &&
+           exc->ignore_x_mode          &&
+           exc->GS.freeVector.x != 0   )
         distance = Round_None(
                      exc,
                      org_dist,
@@ -6169,11 +6106,11 @@
                 org_dist,
                 control_value_cutin,
                 minimum_distance;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     FT_Int      B1           = 0; /* pacify compiler */
     FT_Int      B2           = 0;
     FT_Bool     reverse_move = FALSE;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
 
     minimum_distance    = exc->GS.minimum_distance;
@@ -6181,13 +6118,13 @@
     point               = (FT_UShort)args[0];
     cvtEntry            = (FT_ULong)( args[1] + 1 );
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                   &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    if ( SUBPIXEL_HINTING_INFINALITY                        &&
          exc->ignore_x_mode                                 &&
          exc->GS.freeVector.x != 0                          &&
          !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
       control_value_cutin = minimum_distance = 0;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
 
@@ -6240,8 +6177,8 @@
         cvt_dist = -cvt_dist;
     }
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                          &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    if ( SUBPIXEL_HINTING_INFINALITY                               &&
          exc->ignore_x_mode                                        &&
          exc->GS.freeVector.y != 0                                 &&
          ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
@@ -6251,7 +6188,7 @@
       else if ( cur_dist > 64 && cur_dist < 84 )
         cvt_dist += 32;
     }
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     /* control value cut-in and round */
 
@@ -6286,16 +6223,16 @@
     else
     {
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
       /* do cvt cut-in always in MIRP for sph */
-      if ( SUBPIXEL_HINTING             &&
+      if ( SUBPIXEL_HINTING_INFINALITY  &&
            exc->ignore_x_mode           &&
            exc->GS.gep0 == exc->GS.gep1 )
       {
         if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin )
           cvt_dist = org_dist;
       }
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
       distance = Round_None(
                    exc,
@@ -6319,8 +6256,8 @@
       }
     }
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    if ( SUBPIXEL_HINTING_INFINALITY )
     {
       B1 = exc->zp1.cur[point].y;
 
@@ -6337,12 +6274,12 @@
            ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
         distance += 64;
     }
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     exc->func_move( exc, &exc->zp1, point, distance - cur_dist );
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    if ( SUBPIXEL_HINTING_INFINALITY )
     {
       B2 = exc->zp1.cur[point].y;
 
@@ -6366,7 +6303,7 @@
         exc->func_move( exc, &exc->zp1, point, -( distance - cur_dist ) );
     }
 
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
   Fail:
     exc->GS.rp1 = exc->GS.rp0;
@@ -6391,8 +6328,8 @@
     FT_F26Dot6  distance;
 
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                          &&
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    if ( SUBPIXEL_HINTING_INFINALITY                               &&
          exc->ignore_x_mode                                        &&
          exc->iup_called                                           &&
          ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
@@ -6400,7 +6337,7 @@
       exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     if ( exc->top < exc->GS.loop                  ||
          BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
@@ -6515,6 +6452,7 @@
       R.x = FT_MulDiv( val, dax, discriminant );
       R.y = FT_MulDiv( val, day, discriminant );
 
+      /* XXX: Block in backwards_compatibility and/or post-IUP? */
       exc->zp2.cur[point].x = exc->zp1.cur[a0].x + R.x;
       exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y;
     }
@@ -6522,6 +6460,7 @@
     {
       /* else, take the middle of the middles of A and B */
 
+      /* XXX: Block in backwards_compatibility and/or post-IUP? */
       exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x +
                                 exc->zp1.cur[a1].x +
                                 exc->zp0.cur[b0].x +
@@ -6598,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 ) )
     {
@@ -6646,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;
@@ -6910,6 +6851,23 @@
     FT_Short  contour;       /* current contour */
 
 
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    /* See `ttinterp.h' for details on backwards compatibility mode. */
+    /* Allow IUP until it has been called on both axes.  Immediately */
+    /* return on subsequent ones.                                    */
+    if ( SUBPIXEL_HINTING_MINIMAL     &&
+         exc->backwards_compatibility )
+    {
+      if ( exc->iupx_called && exc->iupy_called )
+        return;
+
+      if ( exc->opcode & 1 )
+        exc->iupx_called = TRUE;
+      else
+        exc->iupy_called = TRUE;
+    }
+#endif
+
     /* ignore empty outlines */
     if ( exc->pts.n_contours == 0 )
       return;
@@ -6933,15 +6891,15 @@
     contour = 0;
     point   = 0;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING   &&
-         exc->ignore_x_mode )
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    if ( SUBPIXEL_HINTING_INFINALITY &&
+         exc->ignore_x_mode          )
     {
       exc->iup_called = TRUE;
       if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
         return;
     }
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     do
     {
@@ -7013,37 +6971,16 @@
     FT_UShort  A;
     FT_ULong   C, P;
     FT_Long    B;
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     FT_UShort  B1, B2;
 
 
-    if ( SUBPIXEL_HINTING                                         &&
+    if ( SUBPIXEL_HINTING_INFINALITY                              &&
          exc->ignore_x_mode                                       &&
          exc->iup_called                                          &&
          ( exc->sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
       goto Fail;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    /* Delta hinting is covered by US Patent 5159668. */
-    if ( exc->face->unpatented_hinting )
-    {
-      FT_Long  n = args[0] * 2;
-
-
-      if ( exc->args < n )
-      {
-        if ( exc->pedantic_hinting )
-          exc->error = FT_THROW( Too_Few_Arguments );
-        n = exc->args;
-      }
-
-      exc->args -= n;
-      exc->new_top = exc->args;
-      return;
-    }
-#endif
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     P    = (FT_ULong)exc->func_cur_ppem( exc );
     nump = (FT_ULong)args[0];   /* some points theoretically may occur more
@@ -7097,9 +7034,9 @@
             B++;
           B *= 1L << ( 6 - exc->GS.delta_shift );
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
 
-          if ( SUBPIXEL_HINTING )
+          if ( SUBPIXEL_HINTING_INFINALITY )
           {
             /*
              *  Allow delta move if
@@ -7156,9 +7093,25 @@
             }
           }
           else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
-            exc->func_move( exc, &exc->zp0, A, B );
+          {
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+            /* See `ttinterp.h' for details on backwards compatibility */
+            /* mode.                                                   */
+            if ( SUBPIXEL_HINTING_MINIMAL     &&
+                 exc->backwards_compatibility )
+            {
+              if ( !( exc->iupx_called && exc->iupy_called )              &&
+                   ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
+                     ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y )        ) )
+                exc->func_move( exc, &exc->zp0, A, B );
+            }
+            else
+#endif
+              exc->func_move( exc, &exc->zp0, A, B );
+          }
         }
       }
       else
@@ -7186,26 +7139,6 @@
     FT_Long   B;
 
 
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    /* Delta hinting is covered by US Patent 5159668. */
-    if ( exc->face->unpatented_hinting )
-    {
-      FT_Long  n = args[0] * 2;
-
-
-      if ( exc->args < n )
-      {
-        if ( exc->pedantic_hinting )
-          exc->error = FT_THROW( Too_Few_Arguments );
-        n = exc->args;
-      }
-
-      exc->args -= n;
-      exc->new_top = exc->args;
-      return;
-    }
-#endif
-
     P    = (FT_ULong)exc->func_cur_ppem( exc );
     nump = (FT_ULong)args[0];
 
@@ -7294,20 +7227,21 @@
   Ins_GETINFO( TT_ExecContext  exc,
                FT_Long*        args )
   {
-    FT_Long  K;
+    FT_Long    K;
+    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( exc->face );
 
 
     K = 0;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     /********************************/
     /* RASTERIZER VERSION           */
     /* Selector Bit:  0             */
     /* Return Bit(s): 0-7           */
     /*                              */
-    if ( SUBPIXEL_HINTING      &&
-         ( args[0] & 1 ) != 0  &&
-         exc->subpixel_hinting )
+    if ( SUBPIXEL_HINTING_INFINALITY &&
+         ( args[0] & 1 ) != 0        &&
+         exc->subpixel_hinting       )
     {
       if ( exc->ignore_x_mode )
       {
@@ -7321,9 +7255,9 @@
         K = TT_INTERPRETER_VERSION_38;
     }
     else
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
       if ( ( args[0] & 1 ) != 0 )
-        K = TT_INTERPRETER_VERSION_35;
+        K = driver->interpreter_version;
 
     /********************************/
     /* GLYPH ROTATED                */
@@ -7331,7 +7265,7 @@
     /* Return Bit(s): 8             */
     /*                              */
     if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated )
-      K |= 0x80;
+      K |= 1 << 8;
 
     /********************************/
     /* GLYPH STRETCHED              */
@@ -7339,19 +7273,83 @@
     /* Return Bit(s): 9             */
     /*                              */
     if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched )
-      K |= 1 << 8;
+      K |= 1 << 9;
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    /********************************/
+    /* VARIATION GLYPH              */
+    /* Selector Bit:  3             */
+    /* Return Bit(s): 10            */
+    /*                              */
+    /* XXX: UNDOCUMENTED!           */
+    if ( (args[0] & 8 ) != 0 && exc->face->blend )
+      K |= 1 << 10;
+#endif
 
     /********************************/
-    /* HINTING FOR GRAYSCALE        */
+    /* BI-LEVEL HINTING AND         */
+    /* GRAYSCALE RENDERING          */
     /* Selector Bit:  5             */
     /* Return Bit(s): 12            */
     /*                              */
     if ( ( args[0] & 32 ) != 0 && exc->grayscale )
       K |= 1 << 12;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    if ( SUBPIXEL_HINTING_MINIMAL )
+    {
+      /********************************/
+      /* HINTING FOR SUBPIXEL         */
+      /* Selector Bit:  6             */
+      /* Return Bit(s): 13            */
+      /*                              */
+      /* v40 does subpixel hinting by default. */
+      if ( ( args[0] & 64 ) != 0 )
+        K |= 1 << 13;
 
-    if ( SUBPIXEL_HINTING                                     &&
+      /********************************/
+      /* VERTICAL LCD SUBPIXELS?      */
+      /* Selector Bit:  8             */
+      /* Return Bit(s): 15            */
+      /*                              */
+      if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd_lean )
+        K |= 1 << 15;
+
+      /********************************/
+      /* SUBPIXEL POSITIONED?         */
+      /* Selector Bit:  10            */
+      /* Return Bit(s): 17            */
+      /*                              */
+      /* XXX: FreeType supports it, dependent on what client does? */
+      if ( ( args[0] & 1024 ) != 0 )
+        K |= 1 << 17;
+
+      /********************************/
+      /* SYMMETRICAL SMOOTHING        */
+      /* Selector Bit:  11            */
+      /* Return Bit(s): 18            */
+      /*                              */
+      /* The only smoothing method FreeType supports unless someone sets */
+      /* FT_LOAD_TARGET_MONO.                                            */
+      if ( ( args[0] & 2048 ) != 0 )
+        K |= 1 << 18;
+
+      /********************************/
+      /* CLEARTYPE HINTING AND        */
+      /* GRAYSCALE RENDERING          */
+      /* Selector Bit:  12            */
+      /* Return Bit(s): 19            */
+      /*                              */
+      /* Grayscale rendering is what FreeType does anyway unless someone */
+      /* sets FT_LOAD_TARGET_MONO or FT_LOAD_TARGET_LCD(_V)              */
+      if ( ( args[0] & 4096 ) != 0 && exc->grayscale_cleartype )
+        K |= 1 << 19;
+    }
+#endif
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+
+    if ( SUBPIXEL_HINTING_INFINALITY                          &&
          exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 )
     {
 
@@ -7424,12 +7422,63 @@
       }
     }
 
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     args[0] = K;
   }
 
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GETVARIATION[]: get normalized variation (blend) coordinates          */
+  /* Opcode range: 0x91                                                    */
+  /* Stack:        --> f2.14...                                            */
+  /*                                                                       */
+  /* XXX: UNDOCUMENTED!  There is no official documentation from Apple for */
+  /*      this bytecode instruction.  Active only if a font has GX         */
+  /*      variation axes.                                                  */
+  /*                                                                       */
+  static void
+  Ins_GETVARIATION( TT_ExecContext  exc,
+                    FT_Long*        args )
+  {
+    FT_UInt    num_axes = exc->face->blend->num_axis;
+    FT_Fixed*  coords   = exc->face->blend->normalizedcoords;
+
+    FT_UInt  i;
+
+
+    if ( BOUNDS( num_axes, exc->stackSize + 1 - exc->top ) )
+    {
+      exc->error = FT_THROW( Stack_Overflow );
+      return;
+    }
+
+    for ( i = 0; i < num_axes; i++ )
+      args[i] = coords[i] >> 2; /* convert 16.16 to 2.14 format */
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GETDATA[]:    no idea what this is good for                           */
+  /* Opcode range: 0x92                                                    */
+  /* Stack:        --> 17                                                  */
+  /*                                                                       */
+  /* XXX: UNDOCUMENTED!  There is no documentation from Apple for this     */
+  /*      very weird bytecode instruction.                                 */
+  /*                                                                       */
+  static void
+  Ins_GETDATA( FT_Long*  args )
+  {
+    args[0] = 17;
+  }
+
+#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
+
+
   static void
   Ins_UNKNOWN( TT_ExecContext  exc )
   {
@@ -7503,10 +7552,11 @@
   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_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     FT_Byte    opcode_pattern[1][2] = {
                   /* #8 TypeMan Talk Align */
                   {
@@ -7517,12 +7567,65 @@
     FT_UShort  opcode_patterns   = 1;
     FT_UShort  opcode_pointer[1] = { 0 };
     FT_UShort  opcode_size[1]    = { 1 };
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     exc->iup_called = FALSE;
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    /* Toggle backwards compatibility according to what font says, except  */
+    /* when it's a `tricky' font that heavily relies on the interpreter to */
+    /* render glyphs correctly, e.g. DFKai-SB.  Backwards compatibility    */
+    /* hacks may break it.                                                 */
+    if ( SUBPIXEL_HINTING_MINIMAL          &&
+         !FT_IS_TRICKY( &exc->face->root ) )
+      exc->backwards_compatibility = !( exc->GS.instruct_control & 4 );
+    else
+      exc->backwards_compatibility = FALSE;
+
+    exc->iupx_called = FALSE;
+    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, or over all points (or contours) 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. */
+    exc->loopcall_counter_max = FT_MAX( 100,
+                                        10 * ( exc->pts.n_points +
+                                               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;
@@ -7565,7 +7668,7 @@
                               ? 2
                               : 12 - ( *opcode_name[exc->opcode] - '0' ),
                               "#" ));
-        for ( n = 0; n < cnt; n++ )
+        for ( n = 1; n <= cnt; n++ )
           FT_TRACE7(( " %d", exc->stack[exc->top - n] ));
         FT_TRACE6(( "\n" ));
       }
@@ -7601,7 +7704,21 @@
         exc->args = 0;
       }
 
-      exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 );
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      if ( exc->opcode == 0x91 )
+      {
+        /* this is very special: GETVARIATION returns */
+        /* a variable number of arguments             */
+
+        /* it is the job of the application to `activate' GX handling, */
+        /* this is, calling any of the GX API functions on the current */
+        /* font to select a variation instance                         */
+        if ( exc->face->blend )
+          exc->new_top = exc->args + exc->face->blend->num_axis;
+      }
+      else
+#endif
+        exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 );
 
       /* `new_top' is the new top of the stack, after the instruction's */
       /* execution.  `top' will be set to `new_top' after the `switch'  */
@@ -7615,9 +7732,9 @@
       exc->step_ins = TRUE;
       exc->error    = FT_Err_Ok;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
 
-      if ( SUBPIXEL_HINTING )
+      if ( SUBPIXEL_HINTING_INFINALITY )
       {
         for ( i = 0; i < opcode_patterns; i++ )
         {
@@ -7646,7 +7763,7 @@
         }
       }
 
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
       {
         FT_Long*  args   = exc->stack + exc->args;
@@ -7794,7 +7911,7 @@
           Ins_ALIGNPTS( exc, args );
           break;
 
-        case 0x28:  /* ???? */
+        case 0x28:  /* RAW */
           Ins_UNKNOWN( exc );
           break;
 
@@ -8146,10 +8263,33 @@
           Ins_INSTCTRL( exc, args );
           break;
 
-        case 0x8F:
+        case 0x8F:  /* ADJUST */
+        case 0x90:  /* ADJUST */
           Ins_UNKNOWN( exc );
           break;
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+        case 0x91:
+          /* it is the job of the application to `activate' GX handling, */
+          /* this is, calling any of the GX API functions on the current */
+          /* font to select a variation instance                         */
+          if ( exc->face->blend )
+            Ins_GETVARIATION( exc, args );
+          else
+            Ins_UNKNOWN( exc );
+          break;
+
+        case 0x92:
+          /* there is at least one MS font (LaoUI.ttf version 5.01) that */
+          /* uses IDEFs for 0x91 and 0x92; for this reason we activate   */
+          /* GETDATA for GX fonts only, similar to GETVARIATION          */
+          if ( exc->face->blend )
+            Ins_GETDATA( args );
+          else
+            Ins_UNKNOWN( exc );
+          break;
+#endif
+
         default:
           if ( opcode >= 0xE0 )
             Ins_MIRP( exc, args );
@@ -8230,7 +8370,7 @@
 
       /* increment instruction counter and check if we didn't */
       /* run this program for too long (e.g. infinite loops). */
-      if ( ++ins_counter > MAX_RUNNABLE_OPCODES )
+      if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES )
         return FT_THROW( Execution_Too_Long );
 
     LSuiteLabel_:
@@ -8247,6 +8387,7 @@
     } while ( !exc->instruction_trap );
 
   LNo_Error_:
+    FT_TRACE4(( "  %d instructions executed\n", ins_counter ));
     return FT_Err_Ok;
 
   LErrorCodeOverflow_:
diff --git a/third_party/freetype/src/truetype/ttinterp.h b/third_party/freetype/src/truetype/ttinterp.h
index 32706d0..6625e16 100644
--- a/third_party/freetype/src/truetype/ttinterp.h
+++ b/third_party/freetype/src/truetype/ttinterp.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType bytecode interpreter (specification).                       */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTINTERP_H__
-#define __TTINTERP_H__
+#ifndef TTINTERP_H_
+#define TTINTERP_H_
 
 #include <ft2build.h>
 #include "ttobjs.h"
@@ -99,7 +99,7 @@
   } TT_CallRec, *TT_CallStack;
 
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
 
   /*************************************************************************/
   /*                                                                       */
@@ -138,7 +138,7 @@
 
   } SPH_Font_Class;
 
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
 
   /*************************************************************************/
@@ -170,6 +170,7 @@
                        pts,
                        twilight;
 
+    FT_Long            pointSize;  /* in 26.6 format */
     FT_Size_Metrics    metrics;
     TT_Size_Metrics    tt_metrics; /* size metrics */
 
@@ -247,9 +248,135 @@
     TT_Set_CVT_Func    func_write_cvt; /* write a cvt entry (in pixels) */
     TT_Set_CVT_Func    func_move_cvt;  /* incr a cvt entry (in pixels)  */
 
-    FT_Bool            grayscale;      /* are we hinting for grayscale? */
+    FT_Bool            grayscale;      /* bi-level hinting and */
+                                       /* grayscale rendering  */
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    /*
+     * Modern TrueType fonts are usually rendered through Microsoft's
+     * collection of rendering techniques called ClearType (e.g., subpixel
+     * rendering and subpixel hinting).  When ClearType was introduced, most
+     * fonts were not ready.  Microsoft decided to implement a backwards
+     * compatibility mode that employed several simple to complicated
+     * assumptions and tricks that modified the interpretation of the
+     * bytecode contained in these fonts to make them look ClearType-y
+     * somehow.  Most (web)fonts that were released since then have come to
+     * rely on these hacks to render correctly, even some of Microsoft's
+     * flagship ClearType fonts (Calibri, Cambria, Segoe UI).
+     *
+     * The minimal subpixel hinting code (interpreter version 40) employs a
+     * small list of font-agnostic hacks to bludgeon non-native-ClearType
+     * fonts (except tricky ones[1]) into submission.  It will not try to
+     * toggle hacks for specific fonts for performance and complexity
+     * reasons.  The focus is on modern (web)fonts rather than legacy fonts
+     * that were made for black-and-white rendering.
+     *
+     * Major hacks
+     *
+     * - Any point movement on the x axis is ignored (cf. `Direct_Move' and
+     *   `Direct_Move_X').  This has the smallest code footprint and single
+     *   biggest effect.  The ClearType way to increase resolution is
+     *   supersampling the x axis, the FreeType way is ignoring instructions
+     *   on the x axis, which gives the same result in the majority of
+     *   cases.
+     *
+     * - Points are not moved post-IUP (neither on the x nor on the y axis),
+     *   except the x component of diagonal moves post-IUP (cf.
+     *   `Direct_Move', `Direct_Move_Y', `Move_Zp2_Point').  Post-IUP
+     *   changes are commonly used to `fix' pixel patterns which has little
+     *   use outside monochrome rendering.
+     *
+     * - SHPIX and DELTAP don't execute unless moving a composite on the
+     *   y axis or moving a previously y touched point.  SHPIX additionally
+     *   denies movement on the x axis (cf. `Ins_SHPIX' and `Ins_DELTAP').
+     *   Both instructions are commonly used to `fix' pixel patterns for
+     *   monochrome or Windows's GDI rendering but make little sense for
+     *   FreeType rendering.  Both can distort the outline.  See [2] for
+     *   details.
+     *
+     * - The hdmx table and modifications to phantom points are ignored.
+     *   Bearings and advance widths remain unchanged (except rounding them
+     *   outside the interpreter!), cf. `compute_glyph_metrics' and
+     *   `TT_Hint_Glyph'.  Letting non-native-ClearType fonts modify spacing
+     *   might mess up spacing.
+     *
+     * Minor hacks
+     *
+     * - FLIPRGON, FLIPRGOFF, and FLIPPT don't execute post-IUP.  This
+     *   prevents dents in e.g. Arial-Regular's `D' and `G' glyphs at
+     *   various sizes.
+     *
+     * (Post-IUP is the state after both IUP[x] and IUP[y] have been
+     * executed.)
+     *
+     * The best results are achieved for fonts that were from the outset
+     * designed with ClearType in mind, meaning they leave the x axis mostly
+     * alone and don't mess with the `final' outline to produce more
+     * pleasing pixel patterns.  The harder the designer tried to produce
+     * very specific patterns (`superhinting') for pre-ClearType-displays,
+     * the worse the results.
+     *
+     * Microsoft defines a way to turn off backwards compatibility and
+     * interpret instructions as before (called `native ClearType')[2][3].
+     * The font designer then regains full control and is responsible for
+     * making the font work correctly with ClearType without any
+     * hand-holding by the interpreter or rasterizer[4].  The v40
+     * interpreter assumes backwards compatibility by default, which can be
+     * turned off the same way by executing the following in the control
+     * program (cf. `Ins_INSTCTRL').
+     *
+     *   #PUSH 4,3
+     *   INSTCTRL[]
+     *
+     * [1] Tricky fonts as FreeType defines them rely on the bytecode
+     *     interpreter to display correctly.  Hacks can interfere with them,
+     *     so they get treated like native ClearType fonts (v40 with
+     *     backwards compatibility turned off).  Cf. `TT_RunIns'.
+     *
+     * [2] Proposed by Microsoft's Greg Hitchcock in
+     *     https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
+     *
+     * [3] Beat Stamm describes it in more detail:
+     *     http://www.beatstamm.com/typography/RTRCh4.htm#Sec12
+     *
+     * [4] The list of `native ClearType' fonts is small at the time of this
+     *     writing; I found the following on a Windows 10 Update 1511
+     *     installation: Constantia, Corbel, Sitka, Malgun Gothic, Microsoft
+     *     JhengHei (Bold and UI Bold), Microsoft YaHei (Bold and UI Bold),
+     *     SimSun, NSimSun, and Yu Gothic.
+     *
+     */
+
+    /* Using v40 implies subpixel hinting.  Used to detect interpreter */
+    /* version switches.  `_lean' to differentiate from the Infinality */
+    /* `subpixel_hinting', which is managed differently.               */
+    FT_Bool            subpixel_hinting_lean;
+
+    /* Long side of a LCD subpixel is vertical (e.g., screen is rotated). */
+    /* `_lean' to differentiate from the Infinality `vertical_lcd', which */
+    /* is managed differently.                                            */
+    FT_Bool            vertical_lcd_lean;
+
+    /* Default to backwards compatibility mode in v40 interpreter.  If  */
+    /* this is false, it implies the interpreter is in v35 or in native */
+    /* ClearType mode.                                                  */
+    FT_Bool            backwards_compatibility;
+
+    /* Useful for detecting and denying post-IUP trickery that is usually */
+    /* used to fix pixel patterns (`superhinting').                       */
+    FT_Bool            iupx_called;
+    FT_Bool            iupy_called;
+
+    /* ClearType hinting and grayscale rendering, as used by Universal */
+    /* Windows Platform apps (Windows 8 and above).  Like the standard */
+    /* colorful ClearType mode, it utilizes a vastly increased virtual */
+    /* resolution on the x axis.  Different from bi-level hinting and  */
+    /* grayscale rendering, the old mode from Win9x days that roughly  */
+    /* adheres to the physical pixel grid on both axes.                */
+    FT_Bool            grayscale_cleartype;
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
     TT_Round_Func      func_round_sphn;   /* subpixel rounding function */
 
     FT_Bool            subpixel_hinting;  /* Using subpixel hinting?       */
@@ -279,7 +406,15 @@
     FT_ULong           sph_in_func_flags;     /* flags to indicate if in   */
                                               /* special functions         */
 
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#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;
 
@@ -382,7 +517,7 @@
 
 FT_END_HEADER
 
-#endif /* __TTINTERP_H__ */
+#endif /* TTINTERP_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/truetype/ttobjs.c b/third_party/freetype/src/truetype/ttobjs.c
index 6060d6f..18aa48a 100644
--- a/third_party/freetype/src/truetype/ttobjs.c
+++ b/third_party/freetype/src/truetype/ttobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Objects manager (body).                                              */
 /*                                                                         */
-/*  Copyright 1996-2015 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,10 +32,6 @@
 #include "ttinterp.h"
 #endif
 
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-#include FT_TRUETYPE_UNPATENTED_H
-#endif
-
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 #include "ttgxvar.h"
 #endif
@@ -121,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   ) ||
@@ -246,7 +242,7 @@
   tt_check_trickyness_sfnt_ids( TT_Face  face )
   {
 #define TRICK_SFNT_IDS_PER_FACE   3
-#define TRICK_SFNT_IDS_NUM_FACES  17
+#define TRICK_SFNT_IDS_NUM_FACES  18
 
     static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES]
                                        [TRICK_SFNT_IDS_PER_FACE] = {
@@ -270,6 +266,11 @@
         { 0x5A30CA3BUL, 0x00009063UL }, /* fpgm */
         { 0x13A42602UL, 0x0000007EUL }  /* prep */
       },
+      { /* DFKaiShu2 */
+        { 0x11E5EAD4UL, 0x00000350UL }, /* cvt  */
+        { 0xA6E78C01UL, 0x00008998UL }, /* fpgm */
+        { 0x13A42602UL, 0x0000007EUL }  /* prep */
+      },
       { /* HuaTianKaiTi */
         { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt  */
         { 0x9C9E48B8UL, 0x0000BEA2UL }, /* fpgm */
@@ -397,11 +398,11 @@
     for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
     {
       if ( !has_cvt  && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length )
-        num_matched_ids[j] ++;
+        num_matched_ids[j]++;
       if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length )
-        num_matched_ids[j] ++;
+        num_matched_ids[j]++;
       if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length )
-        num_matched_ids[j] ++;
+        num_matched_ids[j]++;
       if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
         return TRUE;
     }
@@ -535,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. */
@@ -576,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
@@ -670,35 +664,14 @@
                                      named_style->coords );
           if ( error )
             goto Exit;
+
+          tt_apply_mvar( face );
         }
       }
     }
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
 
-#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING    ) && \
-    !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER )
-
-    {
-      FT_Bool  unpatented_hinting;
-      int      i;
-
-
-      /* Determine whether unpatented hinting is to be used for this face. */
-      unpatented_hinting = FT_BOOL
-        ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL );
-
-      for ( i = 0; i < num_params && !face->unpatented_hinting; i++ )
-        if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING )
-          unpatented_hinting = TRUE;
-
-      if ( !unpatented_hinting )
-        ttface->internal->ignore_unpatented_hinter = TRUE;
-    }
-
-#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING &&
-          !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
-
     /* initialize standard glyph loading routines */
     TT_Init_Glyph_Loading( face );
 
@@ -761,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
   }
@@ -849,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;
@@ -912,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;
@@ -1078,7 +1060,15 @@
     }
 
     /* Fine, now run the font program! */
+
+    /* In case of an error while executing `fpgm', we intentionally don't */
+    /* clean up immediately – bugs in the `fpgm' are so fundamental that  */
+    /* all following hinting calls should fail.  Additionally, `fpgm' is  */
+    /* to be executed just once; calling it again is completely useless   */
+    /* and might even lead to extremely slow behaviour if it is malformed */
+    /* (containing an infinite loop, for example).                        */
     error = tt_size_run_fpgm( size, pedantic );
+    return error;
 
   Exit:
     if ( error )
@@ -1097,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 */
@@ -1130,6 +1122,8 @@
 
       error = tt_size_run_prep( size, pedantic );
     }
+    else
+      error = size->cvt_ready;
 
   Exit:
     return error;
@@ -1206,13 +1200,15 @@
   /*    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;
 
 
@@ -1234,17 +1230,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 ) );
@@ -1272,10 +1277,7 @@
     size->cvt_ready = -1;
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
-    if ( !error )
-      size->ttmetrics.valid = TRUE;
-
-    return error;
+    return FT_Err_Ok;
   }
 
 
@@ -1301,10 +1303,12 @@
 
     TT_Driver  driver = (TT_Driver)ttdriver;
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    driver->interpreter_version = TT_INTERPRETER_VERSION_38;
-#else
     driver->interpreter_version = TT_INTERPRETER_VERSION_35;
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+    driver->interpreter_version = TT_INTERPRETER_VERSION_38;
+#endif
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    driver->interpreter_version = TT_INTERPRETER_VERSION_40;
 #endif
 
 #else /* !TT_USE_BYTECODE_INTERPRETER */
diff --git a/third_party/freetype/src/truetype/ttobjs.h b/third_party/freetype/src/truetype/ttobjs.h
index 9396089..65929e5 100644
--- a/third_party/freetype/src/truetype/ttobjs.h
+++ b/third_party/freetype/src/truetype/ttobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Objects manager (specification).                                     */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTOBJS_H__
-#define __TTOBJS_H__
+#ifndef TTOBJS_H_
+#define TTOBJS_H_
 
 
 #include <ft2build.h>
@@ -72,10 +72,6 @@
     FT_UnitVector  projVector;
     FT_UnitVector  freeVector;
 
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    FT_Bool        both_x_axis;
-#endif
-
     FT_Long        loop;
     FT_F26Dot6     minimum_distance;
     FT_Int         round_state;
@@ -290,6 +286,8 @@
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
 
+    FT_Long            point_size;    /* for the `MPS' bytecode instruction */
+
     FT_UInt            num_function_defs; /* number of function definitions */
     FT_UInt            max_function_defs;
     TT_DefArray        function_defs;     /* table of function definitions  */
@@ -391,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 );
 
 
   /*************************************************************************/
@@ -419,7 +418,7 @@
 
 FT_END_HEADER
 
-#endif /* __TTOBJS_H__ */
+#endif /* TTOBJS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/truetype/ttpic.c b/third_party/freetype/src/truetype/ttpic.c
index 242a6b7..66bd7e1 100644
--- a/third_party/freetype/src/truetype/ttpic.c
+++ b/third_party/freetype/src/truetype/ttpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for truetype module. */
 /*                                                                         */
-/*  Copyright 2009-2015 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/third_party/freetype/src/truetype/ttpic.h b/third_party/freetype/src/truetype/ttpic.h
index 076ae56..1410cd7 100644
--- a/third_party/freetype/src/truetype/ttpic.h
+++ b/third_party/freetype/src/truetype/ttpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for truetype module. */
 /*                                                                         */
-/*  Copyright 2009-2015 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTPIC_H__
-#define __TTPIC_H__
+#ifndef TTPIC_H_
+#define TTPIC_H_
 
 
 #include FT_INTERNAL_PIC_H
@@ -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                       \
@@ -77,7 +82,7 @@
 
  /* */
 
-#endif /* __TTPIC_H__ */
+#endif /* TTPIC_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/truetype/ttpload.c b/third_party/freetype/src/truetype/ttpload.c
index 4647c93..70ac15d 100644
--- a/third_party/freetype/src/truetype/ttpload.c
+++ b/third_party/freetype/src/truetype/ttpload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType-specific tables loader (body).                              */
 /*                                                                         */
-/*  Copyright 1996-2015 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;
     }
@@ -124,8 +134,9 @@
         TT_Table  entry = face->dir_tables;
         TT_Table  limit = entry + face->num_tables;
 
-        FT_Long   pos  = (FT_Long)FT_STREAM_POS();
-        FT_Long   dist = 0x7FFFFFFFL;
+        FT_Long  pos   = (FT_Long)FT_STREAM_POS();
+        FT_Long  dist  = 0x7FFFFFFFL;
+        FT_Bool  found = 0;
 
 
         /* compute the distance to next table in font file */
@@ -135,10 +146,13 @@
 
 
           if ( diff > 0 && diff < dist )
-            dist = diff;
+          {
+            dist  = diff;
+            found = 1;
+          }
         }
 
-        if ( entry == limit )
+        if ( !found )
         {
           /* `loca' is the last table */
           dist = (FT_Long)stream->size - pos;
@@ -218,12 +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,"
-                  " exceeding the end of glyf table (0x%08lx)\n",
+                  " too large offset (0x%08lx) found for glyph index %ld,\n"
+                  "                     "
+                  " exceeding the end of `glyf' table (0x%08lx)\n",
                   pos1, gindex, face->glyf_len ));
       *asize = 0;
       return 0;
@@ -231,11 +246,26 @@
 
     if ( pos2 > face->glyf_len )
     {
-      FT_TRACE1(( "tt_face_get_location:"
-                  " too large offset=0x%08lx found for gid=0x%04lx,"
-                  " 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 */
@@ -494,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;
@@ -511,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 );
 
@@ -530,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/third_party/freetype/src/truetype/ttpload.h b/third_party/freetype/src/truetype/ttpload.h
index bc92369..79079f3 100644
--- a/third_party/freetype/src/truetype/ttpload.h
+++ b/third_party/freetype/src/truetype/ttpload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType-specific tables loader (specification).                     */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTPLOAD_H__
-#define __TTPLOAD_H__
+#ifndef TTPLOAD_H_
+#define TTPLOAD_H_
 
 
 #include <ft2build.h>
@@ -69,7 +69,7 @@
 
 FT_END_HEADER
 
-#endif /* __TTPLOAD_H__ */
+#endif /* TTPLOAD_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/truetype/ttsubpix.c b/third_party/freetype/src/truetype/ttsubpix.c
index 0d391e9..5d803cd 100644
--- a/third_party/freetype/src/truetype/ttsubpix.c
+++ b/third_party/freetype/src/truetype/ttsubpix.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType Subpixel Hinting.                                           */
 /*                                                                         */
-/*  Copyright 2010-2015 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,       */
@@ -27,7 +27,7 @@
 #include "ttsubpix.h"
 
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
 
   /*************************************************************************/
   /*                                                                       */
@@ -1000,12 +1000,12 @@
     }
   }
 
-#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#else /* !TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
   /* ANSI C doesn't like empty source files */
   typedef int  _tt_subpix_dummy;
 
-#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* !TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
 
 /* END */
diff --git a/third_party/freetype/src/truetype/ttsubpix.h b/third_party/freetype/src/truetype/ttsubpix.h
index 9151aa3..c68f97f 100644
--- a/third_party/freetype/src/truetype/ttsubpix.h
+++ b/third_party/freetype/src/truetype/ttsubpix.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType Subpixel Hinting.                                           */
 /*                                                                         */
-/*  Copyright 2010-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __TTSUBPIX_H__
-#define __TTSUBPIX_H__
+#ifndef TTSUBPIX_H_
+#define TTSUBPIX_H_
 
 #include <ft2build.h>
 #include "ttobjs.h"
@@ -27,7 +27,7 @@
 FT_BEGIN_HEADER
 
 
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
 
   /*************************************************************************/
   /*                                                                       */
@@ -100,11 +100,12 @@
 #define SPH_OPTION_SET_COMPATIBLE_WIDTHS   FALSE
 #define SPH_OPTION_SET_RASTERIZER_VERSION  38
 
-#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
+#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
 
 FT_END_HEADER
 
-#endif /* __TTSUBPIX_H__ */
+#endif /* TTSUBPIX_H_ */
+
 
 /* END */
diff --git a/third_party/freetype/src/type1/t1afm.c b/third_party/freetype/src/type1/t1afm.c
index 7f32059..792ea2f 100644
--- a/third_party/freetype/src/type1/t1afm.c
+++ b/third_party/freetype/src/type1/t1afm.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    AFM support for Type 1 fonts (body).                                 */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -197,7 +197,7 @@
     /*   encoding of first glyph (1 byte)     */
     /*   encoding of second glyph (1 byte)    */
     /*   offset (little-endian short)         */
-    for ( ; p < limit ; p += 4 )
+    for ( ; p < limit; p += 4 )
     {
       kp->index1 = FT_Get_Char_Index( t1_face, p[0] );
       kp->index2 = FT_Get_Char_Index( t1_face, p[1] );
@@ -208,7 +208,7 @@
       kp++;
     }
 
-    if ( oldcharmap != NULL )
+    if ( oldcharmap )
       error = FT_Set_Charmap( t1_face, oldcharmap );
     if ( error )
       goto Exit;
@@ -239,9 +239,19 @@
     AFM_ParserRec  parser;
     AFM_FontInfo   fi      = NULL;
     FT_Error       error   = FT_ERR( Unknown_File_Format );
-    T1_Font        t1_font = &( (T1_Face)t1_face )->type1;
+    T1_Face        face    = (T1_Face)t1_face;
+    T1_Font        t1_font = &face->type1;
 
 
+    if ( face->afm_data )
+    {
+      FT_TRACE1(( "T1_Read_Metrics:"
+                  " Freeing previously attached metrics data.\n" ));
+      T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data );
+
+      face->afm_data = NULL;
+    }
+
     if ( FT_NEW( fi )                   ||
          FT_FRAME_ENTER( stream->size ) )
       goto Exit;
@@ -250,7 +260,7 @@
     fi->Ascender  = t1_font->font_bbox.yMax;
     fi->Descender = t1_font->font_bbox.yMin;
 
-    psaux = (PSAux_Service)( (T1_Face)t1_face )->psaux;
+    psaux = (PSAux_Service)face->psaux;
     if ( psaux->afm_parser_funcs )
     {
       error = psaux->afm_parser_funcs->init( &parser,
@@ -298,15 +308,15 @@
       if ( fi->NumKernPair )
       {
         t1_face->face_flags |= FT_FACE_FLAG_KERNING;
-        ( (T1_Face)t1_face )->afm_data = fi;
-        fi = NULL;
+        face->afm_data       = fi;
+        fi                   = NULL;
       }
     }
 
     FT_FRAME_EXIT();
 
   Exit:
-    if ( fi != NULL )
+    if ( fi )
       T1_Done_Metrics( memory, fi );
 
     return error;
diff --git a/third_party/freetype/src/type1/t1afm.h b/third_party/freetype/src/type1/t1afm.h
index 0f42f3e..9f62cd0 100644
--- a/third_party/freetype/src/type1/t1afm.h
+++ b/third_party/freetype/src/type1/t1afm.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    AFM support for Type 1 fonts (specification).                        */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __T1AFM_H__
-#define __T1AFM_H__
+#ifndef T1AFM_H_
+#define T1AFM_H_
 
 #include <ft2build.h>
 #include "t1objs.h"
@@ -48,7 +48,7 @@
 
 FT_END_HEADER
 
-#endif /* __T1AFM_H__ */
+#endif /* T1AFM_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/type1/t1driver.c b/third_party/freetype/src/type1/t1driver.c
index 571f2d2..c208994 100644
--- a/third_party/freetype/src/type1/t1driver.c
+++ b/third_party/freetype/src/type1/t1driver.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 driver interface (body).                                      */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -29,6 +29,7 @@
 
 #include FT_INTERNAL_DEBUG_H
 #include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_HASH_H
 
 #include FT_SERVICE_MULTIPLE_MASTERS_H
 #include FT_SERVICE_GLYPH_DICT_H
@@ -87,8 +88,8 @@
 
   static const FT_Service_GlyphDictRec  t1_service_glyph_dict =
   {
-    (FT_GlyphDict_GetNameFunc)  t1_get_glyph_name,
-    (FT_GlyphDict_NameIndexFunc)t1_get_name_index
+    (FT_GlyphDict_GetNameFunc)  t1_get_glyph_name,    /* get_name   */
+    (FT_GlyphDict_NameIndexFunc)t1_get_name_index     /* name_index */
   };
 
 
@@ -106,7 +107,7 @@
 
   static const FT_Service_PsFontNameRec  t1_service_ps_name =
   {
-    (FT_PsName_GetFunc)t1_get_ps_name
+    (FT_PsName_GetFunc)t1_get_ps_name     /* get_ps_font_name */
   };
 
 
@@ -118,11 +119,16 @@
 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
   static const FT_Service_MultiMastersRec  t1_service_multi_masters =
   {
-    (FT_Get_MM_Func)        T1_Get_Multi_Master,
-    (FT_Set_MM_Design_Func) T1_Set_MM_Design,
-    (FT_Set_MM_Blend_Func)  T1_Set_MM_Blend,
-    (FT_Get_MM_Var_Func)    T1_Get_MM_Var,
-    (FT_Set_Var_Design_Func)T1_Set_Var_Design
+    (FT_Get_MM_Func)        T1_Get_Multi_Master,   /* get_mm         */
+    (FT_Set_MM_Design_Func) T1_Set_MM_Design,      /* set_mm_design  */
+    (FT_Set_MM_Blend_Func)  T1_Set_MM_Blend,       /* set_mm_blend   */
+    (FT_Get_MM_Blend_Func)  T1_Get_MM_Blend,       /* get_mm_blend   */
+    (FT_Get_MM_Var_Func)    T1_Get_MM_Var,         /* get_mm_var     */
+    (FT_Set_Var_Design_Func)T1_Set_Var_Design,     /* set_var_design */
+    (FT_Get_Var_Design_Func)T1_Get_Var_Design,     /* get_var_design */
+
+    (FT_Get_Var_Blend_Func) NULL,                  /* get_var_blend  */
+    (FT_Done_Blend_Func)    T1_Done_Blend          /* done_blend     */
   };
 #endif
 
@@ -329,13 +335,37 @@
       break;
 
     case PS_DICT_SUBR:
-      if ( idx < (FT_UInt)type1->num_subrs )
       {
-        retval = type1->subrs_len[idx] + 1;
-        if ( value && value_len >= retval )
+        FT_Bool  ok = 0;
+
+
+        if ( type1->subrs_hash )
         {
-          ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 );
-          ((FT_Char *)value)[retval - 1] = (FT_Char)'\0';
+          /* convert subr index to array index */
+          size_t*  val = ft_hash_num_lookup( (FT_Int)idx,
+                                             type1->subrs_hash );
+
+
+          if ( val )
+          {
+            idx = *val;
+            ok  = 1;
+          }
+        }
+        else
+        {
+          if ( idx < (FT_UInt)type1->num_subrs )
+            ok = 1;
+        }
+
+        if ( ok )
+        {
+          retval = type1->subrs_len[idx] + 1;
+          if ( value && value_len >= retval )
+          {
+            ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 );
+            ((FT_Char *)value)[retval - 1] = (FT_Char)'\0';
+          }
         }
       }
       break;
@@ -567,18 +597,18 @@
 
   static const FT_Service_PsInfoRec  t1_service_ps_info =
   {
-    (PS_GetFontInfoFunc)   t1_ps_get_font_info,
-    (PS_GetFontExtraFunc)  t1_ps_get_font_extra,
-    (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names,
-    (PS_GetFontPrivateFunc)t1_ps_get_font_private,
-    (PS_GetFontValueFunc)  t1_ps_get_font_value,
+    (PS_GetFontInfoFunc)   t1_ps_get_font_info,    /* ps_get_font_info    */
+    (PS_GetFontExtraFunc)  t1_ps_get_font_extra,   /* ps_get_font_extra   */
+    (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names,  /* ps_has_glyph_names  */
+    (PS_GetFontPrivateFunc)t1_ps_get_font_private, /* ps_get_font_private */
+    (PS_GetFontValueFunc)  t1_ps_get_font_value,   /* ps_get_font_value   */
   };
 
 
 #ifndef T1_CONFIG_OPTION_NO_AFM
   static const FT_Service_KerningRec  t1_service_kerning =
   {
-    T1_Get_Track_Kerning,
+    T1_Get_Track_Kerning,       /* get_track */
   };
 #endif
 
@@ -689,36 +719,37 @@
       0x10000L,
       0x20000L,
 
-      0,   /* format interface */
+      NULL,    /* module-specific interface */
 
-      T1_Driver_Init,
-      T1_Driver_Done,
-      Get_Interface,
+      T1_Driver_Init,           /* FT_Module_Constructor  module_init   */
+      T1_Driver_Done,           /* FT_Module_Destructor   module_done   */
+      Get_Interface,            /* FT_Module_Requester    get_interface */
     },
 
     sizeof ( T1_FaceRec ),
     sizeof ( T1_SizeRec ),
     sizeof ( T1_GlyphSlotRec ),
 
-    T1_Face_Init,
-    T1_Face_Done,
-    T1_Size_Init,
-    T1_Size_Done,
-    T1_GlyphSlot_Init,
-    T1_GlyphSlot_Done,
+    T1_Face_Init,               /* FT_Face_InitFunc  init_face */
+    T1_Face_Done,               /* FT_Face_DoneFunc  done_face */
+    T1_Size_Init,               /* FT_Size_InitFunc  init_size */
+    T1_Size_Done,               /* FT_Size_DoneFunc  done_size */
+    T1_GlyphSlot_Init,          /* FT_Slot_InitFunc  init_slot */
+    T1_GlyphSlot_Done,          /* FT_Slot_DoneFunc  done_slot */
 
-    T1_Load_Glyph,
+    T1_Load_Glyph,              /* FT_Slot_LoadFunc  load_glyph */
 
 #ifdef T1_CONFIG_OPTION_NO_AFM
-    0,                     /* FT_Face_GetKerningFunc */
-    0,                     /* FT_Face_AttachFunc     */
+    NULL,                       /* FT_Face_GetKerningFunc   get_kerning  */
+    NULL,                       /* FT_Face_AttachFunc       attach_file  */
 #else
-    Get_Kerning,
-    T1_Read_Metrics,
+    Get_Kerning,                /* FT_Face_GetKerningFunc   get_kerning  */
+    T1_Read_Metrics,            /* FT_Face_AttachFunc       attach_file  */
 #endif
-    T1_Get_Advances,
-    T1_Size_Request,
-    0                      /* FT_Size_SelectFunc     */
+    T1_Get_Advances,            /* FT_Face_GetAdvancesFunc  get_advances */
+
+    T1_Size_Request,            /* FT_Size_RequestFunc  request_size */
+    NULL                        /* FT_Size_SelectFunc   select_size  */
   };
 
 
diff --git a/third_party/freetype/src/type1/t1driver.h b/third_party/freetype/src/type1/t1driver.h
index 34bcf81..2927864 100644
--- a/third_party/freetype/src/type1/t1driver.h
+++ b/third_party/freetype/src/type1/t1driver.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level Type 1 driver interface (specification).                  */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __T1DRIVER_H__
-#define __T1DRIVER_H__
+#ifndef T1DRIVER_H_
+#define T1DRIVER_H_
 
 
 #include <ft2build.h>
@@ -36,7 +36,7 @@
 
 FT_END_HEADER
 
-#endif /* __T1DRIVER_H__ */
+#endif /* T1DRIVER_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/type1/t1errors.h b/third_party/freetype/src/type1/t1errors.h
index fc7a9bd..492dbb4 100644
--- a/third_party/freetype/src/type1/t1errors.h
+++ b/third_party/freetype/src/type1/t1errors.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 error codes (specification only).                             */
 /*                                                                         */
-/*  Copyright 2001-2015 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,       */
@@ -22,12 +22,12 @@
   /*                                                                       */
   /*************************************************************************/
 
-#ifndef __T1ERRORS_H__
-#define __T1ERRORS_H__
+#ifndef T1ERRORS_H_
+#define T1ERRORS_H_
 
 #include FT_MODULE_ERRORS_H
 
-#undef __FTERRORS_H__
+#undef FTERRORS_H_
 
 #undef  FT_ERR_PREFIX
 #define FT_ERR_PREFIX  T1_Err_
@@ -35,7 +35,7 @@
 
 #include FT_ERRORS_H
 
-#endif /* __T1ERRORS_H__ */
+#endif /* T1ERRORS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/type1/t1gload.c b/third_party/freetype/src/type1/t1gload.c
index 85ada2e..aaf19b6 100644
--- a/third_party/freetype/src/type1/t1gload.c
+++ b/third_party/freetype/src/type1/t1gload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 Glyph Loader (body).                                          */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -183,6 +183,7 @@
     decoder.num_subrs     = type1->num_subrs;
     decoder.subrs         = type1->subrs;
     decoder.subrs_len     = type1->subrs_len;
+    decoder.subrs_hash    = type1->subrs_hash;
 
     decoder.buildchar     = face->buildchar;
     decoder.len_buildchar = face->len_buildchar;
@@ -245,9 +246,10 @@
     decoder.builder.metrics_only = 1;
     decoder.builder.load_points  = 0;
 
-    decoder.num_subrs = type1->num_subrs;
-    decoder.subrs     = type1->subrs;
-    decoder.subrs_len = type1->subrs_len;
+    decoder.num_subrs  = type1->num_subrs;
+    decoder.subrs      = type1->subrs;
+    decoder.subrs_len  = type1->subrs_len;
+    decoder.subrs_hash = type1->subrs_hash;
 
     decoder.buildchar     = face->buildchar;
     decoder.len_buildchar = face->len_buildchar;
@@ -346,6 +348,7 @@
     decoder.num_subrs     = type1->num_subrs;
     decoder.subrs         = type1->subrs;
     decoder.subrs_len     = type1->subrs_len;
+    decoder.subrs_hash    = type1->subrs_hash;
 
     decoder.buildchar     = face->buildchar;
     decoder.len_buildchar = face->len_buildchar;
diff --git a/third_party/freetype/src/type1/t1gload.h b/third_party/freetype/src/type1/t1gload.h
index 05f60d5..cc4d5e7 100644
--- a/third_party/freetype/src/type1/t1gload.h
+++ b/third_party/freetype/src/type1/t1gload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 Glyph Loader (specification).                                 */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __T1GLOAD_H__
-#define __T1GLOAD_H__
+#ifndef T1GLOAD_H_
+#define T1GLOAD_H_
 
 
 #include <ft2build.h>
@@ -47,7 +47,7 @@
 
 FT_END_HEADER
 
-#endif /* __T1GLOAD_H__ */
+#endif /* T1GLOAD_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/type1/t1load.c b/third_party/freetype/src/type1/t1load.c
index dbf4eaf..f5c661f 100644
--- a/third_party/freetype/src/type1/t1load.c
+++ b/third_party/freetype/src/type1/t1load.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 font loader (body).                                           */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -66,6 +66,7 @@
 #include FT_MULTIPLE_MASTERS_H
 #include FT_INTERNAL_TYPE1_TYPES_H
 #include FT_INTERNAL_CALC_H
+#include FT_INTERNAL_HASH_H
 
 #include "t1load.h"
 #include "t1errors.h"
@@ -236,7 +237,7 @@
     if ( ncv <= axismap->blend_points[0] )
       return INT_TO_FIXED( axismap->design_points[0] );
 
-    for ( j = 1; j < axismap->num_points; ++j )
+    for ( j = 1; j < axismap->num_points; j++ )
     {
       if ( ncv <= axismap->blend_points[j] )
         return INT_TO_FIXED( axismap->design_points[j - 1] ) +
@@ -320,12 +321,12 @@
 
     mmvar->num_axis        = mmaster.num_axis;
     mmvar->num_designs     = mmaster.num_designs;
-    mmvar->num_namedstyles = ~0U;                        /* Does not apply */
+    mmvar->num_namedstyles = 0;                           /* Not supported */
     mmvar->axis            = (FT_Var_Axis*)&mmvar[1];
                                       /* Point to axes after MM_Var struct */
     mmvar->namedstyle      = NULL;
 
-    for ( i = 0 ; i < mmaster.num_axis; ++i )
+    for ( i = 0; i < mmaster.num_axis; i++ )
     {
       mmvar->axis[i].name    = mmaster.axis[i].name;
       mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum);
@@ -336,6 +337,9 @@
       mmvar->axis[i].strid   = ~0U;                      /* Does not apply */
       mmvar->axis[i].tag     = ~0U;                      /* Does not apply */
 
+      if ( !mmvar->axis[i].name )
+        continue;
+
       if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 )
         mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' );
       else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 )
@@ -350,7 +354,7 @@
                         axiscoords,
                         blend->num_axis );
 
-      for ( i = 0; i < mmaster.num_axis; ++i )
+      for ( i = 0; i < mmaster.num_axis; i++ )
         mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i],
                                             axiscoords[i] );
     }
@@ -409,6 +413,41 @@
 
 
   FT_LOCAL_DEF( FT_Error )
+  T1_Get_MM_Blend( T1_Face    face,
+                   FT_UInt    num_coords,
+                   FT_Fixed*  coords )
+  {
+    PS_Blend  blend = face->blend;
+
+    FT_Fixed  axiscoords[4];
+    FT_UInt   i, nc;
+
+
+    if ( !blend )
+      return FT_THROW( Invalid_Argument );
+
+    mm_weights_unmap( blend->weight_vector,
+                      axiscoords,
+                      blend->num_axis );
+
+    nc = num_coords;
+    if ( num_coords > blend->num_axis )
+    {
+      FT_TRACE2(( "T1_Get_MM_Blend: only using first %d of %d coordinates\n",
+                  blend->num_axis, num_coords ));
+      nc = blend->num_axis;
+    }
+
+    for ( i = 0; i < nc; i++ )
+      coords[i] = axiscoords[i];
+    for ( ; i < num_coords; i++ )
+      coords[i] = 0x8000;
+
+    return FT_Err_Ok;
+  }
+
+
+  FT_LOCAL_DEF( FT_Error )
   T1_Set_MM_Design( T1_Face   face,
                     FT_UInt   num_coords,
                     FT_Long*  coords )
@@ -500,13 +539,49 @@
      if ( num_coords > T1_MAX_MM_AXIS )
        num_coords = T1_MAX_MM_AXIS;
 
-     for ( i = 0; i < num_coords; ++i )
+     for ( i = 0; i < num_coords; i++ )
        lcoords[i] = FIXED_TO_INT( coords[i] );
 
      return T1_Set_MM_Design( face, num_coords, lcoords );
   }
 
 
+  FT_LOCAL_DEF( FT_Error )
+  T1_Get_Var_Design( T1_Face    face,
+                     FT_UInt    num_coords,
+                     FT_Fixed*  coords )
+  {
+    PS_Blend  blend = face->blend;
+
+    FT_Fixed  axiscoords[4];
+    FT_UInt   i, nc;
+
+
+    if ( !blend )
+      return FT_THROW( Invalid_Argument );
+
+    mm_weights_unmap( blend->weight_vector,
+                      axiscoords,
+                      blend->num_axis );
+
+    nc = num_coords;
+    if ( num_coords > blend->num_axis )
+    {
+      FT_TRACE2(( "T1_Get_Var_Design:"
+                  " only using first %d of %d coordinates\n",
+                  blend->num_axis, num_coords ));
+      nc = blend->num_axis;
+    }
+
+    for ( i = 0; i < nc; i++ )
+      coords[i] = mm_axis_unmap( &blend->design_map[i], axiscoords[i] );
+    for ( ; i < num_coords; i++ )
+      coords[i] = 0;
+
+    return FT_Err_Ok;
+  }
+
+
   FT_LOCAL_DEF( void )
   T1_Done_Blend( T1_Face  face )
   {
@@ -1401,6 +1476,7 @@
     FT_Memory  memory = parser->root.memory;
     FT_Error   error;
     FT_Int     num_subrs;
+    FT_UInt    count;
 
     PSAux_Service  psaux = (PSAux_Service)face->psaux;
 
@@ -1420,6 +1496,47 @@
     }
 
     num_subrs = (FT_Int)T1_ToInt( parser );
+    if ( num_subrs < 0 )
+    {
+      parser->root.error = FT_THROW( Invalid_File_Format );
+      return;
+    }
+
+    /* we certainly need more than 8 bytes per subroutine */
+    if ( parser->root.limit >= parser->root.cursor                     &&
+         num_subrs > ( parser->root.limit - parser->root.cursor ) >> 3 )
+    {
+      /*
+       * There are two possibilities.  Either the font contains an invalid
+       * value for `num_subrs', or we have a subsetted font where the
+       * subroutine indices are not adjusted, e.g.
+       *
+       *   /Subrs 812 array
+       *     dup 0 { ... } NP
+       *     dup 51 { ... } NP
+       *     dup 681 { ... } NP
+       *   ND
+       *
+       * In both cases, we use a number hash that maps from subr indices to
+       * actual array elements.
+       */
+
+      FT_TRACE0(( "parse_subrs: adjusting number of subroutines"
+                  " (from %d to %d)\n",
+                  num_subrs,
+                  ( parser->root.limit - parser->root.cursor ) >> 3 ));
+      num_subrs = ( parser->root.limit - parser->root.cursor ) >> 3;
+
+      if ( !loader->subrs_hash )
+      {
+        if ( FT_NEW( loader->subrs_hash ) )
+          goto Fail;
+
+        error = ft_hash_num_init( loader->subrs_hash, memory );
+        if ( error )
+          goto Fail;
+      }
+    }
 
     /* position the parser right before the `dup' of the first subr */
     T1_Skip_PS_Token( parser );         /* `array' */
@@ -1440,7 +1557,7 @@
     /*                         */
     /*   `index' + binary data */
     /*                         */
-    for (;;)
+    for ( count = 0; ; count++ )
     {
       FT_Long   idx;
       FT_ULong  size;
@@ -1476,6 +1593,14 @@
         T1_Skip_Spaces  ( parser );
       }
 
+      /* if we use a hash, the subrs index is the key, and a running */
+      /* counter specified for `T1_Add_Table' acts as the value      */
+      if ( loader->subrs_hash )
+      {
+        ft_hash_num_insert( idx, count, loader->subrs_hash, memory );
+        idx = count;
+      }
+
       /* with synthetic fonts it is possible we get here twice */
       if ( loader->num_subrs )
         continue;
@@ -1487,7 +1612,7 @@
       /*                                                         */
       if ( face->type1.private_dict.lenIV >= 0 )
       {
-        FT_Byte*  temp;
+        FT_Byte*  temp = NULL;
 
 
         /* some fonts define empty subr records -- this is not totally */
@@ -1691,7 +1816,7 @@
         if ( face->type1.private_dict.lenIV >= 0 &&
              n < num_glyphs + TABLE_EXTEND       )
         {
-          FT_Byte*  temp;
+          FT_Byte*  temp = NULL;
 
 
           if ( size <= (FT_ULong)face->type1.private_dict.lenIV )
@@ -1719,6 +1844,12 @@
       }
     }
 
+    if ( !n )
+    {
+      error = FT_THROW( Invalid_File_Format );
+      goto Fail;
+    }
+
     loader->num_glyphs = n;
 
     /* if /.notdef is found but does not occupy index 0, do our magic. */
@@ -2047,7 +2178,7 @@
                 parser->root.error = t1_load_keyword( face,
                                                       loader,
                                                       keyword );
-                if ( parser->root.error != FT_Err_Ok )
+                if ( parser->root.error )
                 {
                   if ( FT_ERR_EQ( parser->root.error, Ignore ) )
                     parser->root.error = FT_Err_Ok;
@@ -2086,18 +2217,7 @@
   {
     FT_UNUSED( face );
 
-    FT_MEM_ZERO( loader, sizeof ( *loader ) );
-    loader->num_glyphs = 0;
-    loader->num_chars  = 0;
-
-    /* initialize the tables -- simply set their `init' field to 0 */
-    loader->encoding_table.init  = 0;
-    loader->charstrings.init     = 0;
-    loader->glyph_names.init     = 0;
-    loader->subrs.init           = 0;
-    loader->swap_table.init      = 0;
-    loader->fontdata             = 0;
-    loader->keywords_encountered = 0;
+    FT_ZERO( loader );
   }
 
 
@@ -2105,6 +2225,7 @@
   t1_done_loader( T1_Loader  loader )
   {
     T1_Parser  parser = &loader->parser;
+    FT_Memory  memory = parser->root.memory;
 
 
     /* finalize tables */
@@ -2114,6 +2235,10 @@
     T1_Release_Table( &loader->swap_table );
     T1_Release_Table( &loader->subrs );
 
+    /* finalize hash */
+    ft_hash_num_free( loader->subrs_hash, memory );
+    FT_FREE( loader->subrs_hash );
+
     /* finalize parser */
     T1_Finalize_Parser( parser );
   }
@@ -2230,11 +2355,15 @@
 
     if ( loader.subrs.init )
     {
-      loader.subrs.init  = 0;
       type1->num_subrs   = loader.num_subrs;
       type1->subrs_block = loader.subrs.block;
       type1->subrs       = loader.subrs.elements;
       type1->subrs_len   = loader.subrs.lengths;
+      type1->subrs_hash  = loader.subrs_hash;
+
+      /* prevent `t1_done_loader' from freeing the propagated data */
+      loader.subrs.init = 0;
+      loader.subrs_hash = NULL;
     }
 
     if ( !IS_INCREMENTAL )
diff --git a/third_party/freetype/src/type1/t1load.h b/third_party/freetype/src/type1/t1load.h
index de422e7..2d86984 100644
--- a/third_party/freetype/src/type1/t1load.h
+++ b/third_party/freetype/src/type1/t1load.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 font loader (specification).                                  */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __T1LOAD_H__
-#define __T1LOAD_H__
+#ifndef T1LOAD_H_
+#define T1LOAD_H_
 
 
 #include <ft2build.h>
@@ -46,6 +46,7 @@
 
     FT_Int        num_subrs;
     PS_TableRec   subrs;
+    FT_Hash       subrs_hash;
     FT_Bool       fontdata;
 
     FT_UInt       keywords_encountered; /* T1_LOADER_ENCOUNTERED_XXX */
@@ -69,7 +70,7 @@
   T1_Get_Multi_Master( T1_Face           face,
                        FT_Multi_Master*  master );
 
-  FT_LOCAL_DEF( FT_Error )
+  FT_LOCAL( FT_Error )
   T1_Get_MM_Var( T1_Face      face,
                  FT_MM_Var*  *master );
 
@@ -79,11 +80,21 @@
                    FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
+  T1_Get_MM_Blend( T1_Face    face,
+                   FT_UInt    num_coords,
+                   FT_Fixed*  coords );
+
+  FT_LOCAL( FT_Error )
   T1_Set_MM_Design( T1_Face   face,
                     FT_UInt   num_coords,
                     FT_Long*  coords );
 
-  FT_LOCAL_DEF( FT_Error )
+  FT_LOCAL( FT_Error )
+  T1_Get_Var_Design( T1_Face    face,
+                     FT_UInt    num_coords,
+                     FT_Fixed*  coords );
+
+  FT_LOCAL( FT_Error )
   T1_Set_Var_Design( T1_Face    face,
                      FT_UInt    num_coords,
                      FT_Fixed*  coords );
@@ -96,7 +107,7 @@
 
 FT_END_HEADER
 
-#endif /* __T1LOAD_H__ */
+#endif /* T1LOAD_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/type1/t1objs.c b/third_party/freetype/src/type1/t1objs.c
index d921063..5637035 100644
--- a/third_party/freetype/src/type1/t1objs.c
+++ b/third_party/freetype/src/type1/t1objs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 objects manager (body).                                       */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -67,7 +67,7 @@
                             "pshinter" );
     return ( module && pshinter && pshinter->get_globals_funcs )
            ? pshinter->get_globals_funcs( module )
-           : 0 ;
+           : 0;
   }
 
 
@@ -247,6 +247,9 @@
     FT_FREE( type1->subrs );
     FT_FREE( type1->subrs_len );
 
+    ft_hash_num_free( type1->subrs_hash, memory );
+    FT_FREE( type1->subrs_hash );
+
     FT_FREE( type1->subrs_block );
     FT_FREE( type1->charstrings_block );
     FT_FREE( type1->glyph_names_block );
diff --git a/third_party/freetype/src/type1/t1objs.h b/third_party/freetype/src/type1/t1objs.h
index 6b4f3cb..39d26bf 100644
--- a/third_party/freetype/src/type1/t1objs.h
+++ b/third_party/freetype/src/type1/t1objs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 objects manager (specification).                              */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __T1OBJS_H__
-#define __T1OBJS_H__
+#ifndef T1OBJS_H_
+#define T1OBJS_H_
 
 
 #include <ft2build.h>
@@ -154,7 +154,7 @@
 
 FT_END_HEADER
 
-#endif /* __T1OBJS_H__ */
+#endif /* T1OBJS_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/type1/t1parse.c b/third_party/freetype/src/type1/t1parse.c
index 0b68502..18dd264 100644
--- a/third_party/freetype/src/type1/t1parse.c
+++ b/third_party/freetype/src/type1/t1parse.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 parser (body).                                                */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -437,7 +437,7 @@
                 *cur == '\t'               ||
                 (test_cr && *cur == '\r' ) ||
                 *cur == '\n'               ) )
-        ++cur;
+        cur++;
       if ( cur >= limit )
       {
         FT_ERROR(( "T1_Get_Private_Dict:"
diff --git a/third_party/freetype/src/type1/t1parse.h b/third_party/freetype/src/type1/t1parse.h
index 93b02e3..3396680 100644
--- a/third_party/freetype/src/type1/t1parse.h
+++ b/third_party/freetype/src/type1/t1parse.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 parser (specification).                                       */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */
@@ -16,8 +16,8 @@
 /***************************************************************************/
 
 
-#ifndef __T1PARSE_H__
-#define __T1PARSE_H__
+#ifndef T1PARSE_H_
+#define T1PARSE_H_
 
 
 #include <ft2build.h>
@@ -123,7 +123,7 @@
 
 FT_END_HEADER
 
-#endif /* __T1PARSE_H__ */
+#endif /* T1PARSE_H_ */
 
 
 /* END */
diff --git a/third_party/freetype/src/type1/t1tokens.h b/third_party/freetype/src/type1/t1tokens.h
index 3992652..ca0c55f 100644
--- a/third_party/freetype/src/type1/t1tokens.h
+++ b/third_party/freetype/src/type1/t1tokens.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 tokenizer (specification).                                    */
 /*                                                                         */
-/*  Copyright 1996-2015 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/third_party/freetype/src/type1/type1.c b/third_party/freetype/src/type1/type1.c
index 4c70ea7..bfe0e43 100644
--- a/third_party/freetype/src/type1/type1.c
+++ b/third_party/freetype/src/type1/type1.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType Type 1 driver component (body only).                        */
 /*                                                                         */
-/*  Copyright 1996-2015 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,       */