Update to freetype 2.6.0

Bug 18751561

Change-Id: Ia8c081f8fd38a1f78c72d30234c5ace8cfffe6a9
diff --git a/Android.mk b/Android.mk
index ae098d1..b2b780b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,10 +1,10 @@
 # this is now the default FreeType build for Android
 #
 ifndef USE_FREETYPE
-USE_FREETYPE := 2.4.2
+USE_FREETYPE := 2.6.0
 endif
 
-ifeq ($(USE_FREETYPE),2.4.2)
+ifeq ($(USE_FREETYPE),2.6.0)
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
@@ -14,34 +14,33 @@
 LOCAL_ARM_MODE := arm
 
 LOCAL_SRC_FILES:= \
-	src/base/ftbbox.c \
-	src/base/ftbitmap.c \
-	src/base/ftfstype.c \
-	src/base/ftglyph.c \
-	src/base/ftlcdfil.c \
-	src/base/ftstroke.c \
-	src/base/fttype1.c \
-	src/base/ftxf86.c \
-	src/base/ftbase.c \
-	src/base/ftsystem.c \
-	src/base/ftinit.c \
-	src/base/ftgasp.c \
-	src/base/ftmm.c \
-	src/gzip/ftgzip.c \
-	src/raster/raster.c \
-	src/sfnt/sfnt.c \
-	src/smooth/smooth.c \
-	src/autofit/autofit.c \
-	src/truetype/truetype.c \
-	src/cff/cff.c \
-	src/psnames/psnames.c \
-	src/pshinter/pshinter.c
+    src/base/ftbbox.c \
+    src/base/ftbitmap.c \
+    src/base/ftfntfmt.c \
+    src/base/ftfstype.c \
+    src/base/ftglyph.c \
+    src/base/ftlcdfil.c \
+    src/base/ftstroke.c \
+    src/base/fttype1.c \
+    src/base/ftbase.c \
+    src/base/ftsystem.c \
+    src/base/ftinit.c \
+    src/base/ftgasp.c \
+    src/base/ftmm.c \
+    src/gzip/ftgzip.c \
+    src/raster/raster.c \
+    src/sfnt/sfnt.c \
+    src/smooth/smooth.c \
+    src/autofit/autofit.c \
+    src/truetype/truetype.c \
+    src/cff/cff.c \
+    src/psnames/psnames.c \
+    src/pshinter/pshinter.c
 
 LOCAL_C_INCLUDES += \
-	$(LOCAL_PATH)/builds \
-	$(LOCAL_PATH)/include \
-	external/libpng \
-	external/zlib
+    $(LOCAL_PATH)/include \
+    external/libpng \
+    external/zlib
 
 LOCAL_CFLAGS += -W -Wall
 LOCAL_CFLAGS += -fPIC -DPIC
diff --git a/CleanSpec.mk b/CleanSpec.mk
index b84e1b6..b9cafef 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -47,3 +47,5 @@
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
+
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libft2_*)
diff --git a/README.android b/README.android
new file mode 100644
index 0000000..ed61907
--- /dev/null
+++ b/README.android
@@ -0,0 +1,4 @@
+Freetype
+
+Not all modules in include/config/ftmodule.h are enabled.
+Some options in include/config/ftoption.h are enabled/disabled.
diff --git a/builds/ft2unix.h b/builds/ft2unix.h
deleted file mode 100644
index 6a3b8d9..0000000
--- a/builds/ft2unix.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ft2build.h                                                             */
-/*                                                                         */
-/*    Build macros of the FreeType 2 library.                              */
-/*                                                                         */
-/*  Copyright 1996-2001, 2003, 2006 by                                     */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* This is a Unix-specific version of <ft2build.h> that should be used   */
-  /* exclusively *after* installation of the library.                      */
-  /*                                                                       */
-  /* It assumes that `/usr/local/include/freetype2' (or whatever is        */
-  /* returned by the `freetype-config --cflags' or `pkg-config --cflags'   */
-  /* command) is in your compilation include path.                         */
-  /*                                                                       */
-  /* We don't need to do anything special in this release.  However, for   */
-  /* a future FreeType 2 release, the following installation changes will  */
-  /* be performed:                                                         */
-  /*                                                                       */
-  /*   - The contents of `freetype-2.x/include/freetype' will be installed */
-  /*     to `/usr/local/include/freetype2' instead of                      */
-  /*     `/usr/local/include/freetype2/freetype'.                          */
-  /*                                                                       */
-  /*   - This file will #include <freetype2/config/ftheader.h>, instead    */
-  /*     of <freetype/config/ftheader.h>.                                  */
-  /*                                                                       */
-  /*   - The contents of `ftheader.h' will be processed with `sed' to      */
-  /*     replace all `<freetype/xxx>' with `<freetype2/xxx>'.              */
-  /*                                                                       */
-  /*   - Adding `/usr/local/include/freetype2' to your compilation include */
-  /*     path will not be necessary anymore.                               */
-  /*                                                                       */
-  /* These changes will be transparent to client applications which use    */
-  /* freetype-config (or pkg-config).  No modifications will be necessary  */
-  /* to compile with the new scheme.                                       */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#ifndef __FT2_BUILD_UNIX_H__
-#define __FT2_BUILD_UNIX_H__
-
-  /* `<prefix>/include/freetype2' must be in your current inclusion path */
-#include <freetype/config/ftheader.h>
-
-#endif /* __FT2_BUILD_UNIX_H__ */
-
-
-/* END */
diff --git a/include/config/ftconfig.h b/include/config/ftconfig.h
index 89a0f8f..086db76 100644
--- a/include/config/ftconfig.h
+++ b/include/config/ftconfig.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    ANSI-specific configuration file (specification only).               */
 /*                                                                         */
-/*  Copyright 1996-2004, 2006-2008, 2010-2011, 2013, 2014 by               */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -266,7 +266,16 @@
 #define FT_INT64   long
 #define FT_UINT64  unsigned long
 
-#elif defined( _MSC_VER ) && _MSC_VER >= 900  /* Visual C++ (and Intel C++) */
+  /*************************************************************************/
+  /*                                                                       */
+  /* A 64-bit data type may create compilation problems if you compile     */
+  /* in strict ANSI mode.  To avoid them, we disable other 64-bit data     */
+  /* types if __STDC__ is defined.  You can however ignore this rule       */
+  /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro.     */
+  /*                                                                       */
+#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 )
+
+#if defined( _MSC_VER ) && _MSC_VER >= 900  /* Visual C++ (and Intel C++) */
 
   /* this compiler provides the __int64 type */
 #define FT_LONG64
@@ -300,39 +309,38 @@
 #define FT_INT64   long long int
 #define FT_UINT64  unsigned long long int
 
+#endif /* _MSC_VER */
+
 #endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
 
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* A 64-bit data type will create compilation problems if you compile    */
-  /* in strict ANSI mode.  To avoid them, we disable its use if __STDC__   */
-  /* is defined.  You can however ignore this rule by defining the         */
-  /* FT_CONFIG_OPTION_FORCE_INT64 configuration macro.                     */
-  /*                                                                       */
-#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 )
-
-#ifdef __STDC__
-
-  /* undefine the 64-bit macros in strict ANSI compilation mode */
-#undef FT_LONG64
-#undef FT_INT64
-
-#endif /* __STDC__ */
-
-#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */
-
 #ifdef FT_LONG64
   typedef FT_INT64   FT_Int64;
   typedef FT_UINT64  FT_UInt64;
 #endif
 
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* miscellaneous                                                         */
+  /*                                                                       */
+  /*************************************************************************/
+
+
 #define FT_BEGIN_STMNT  do {
 #define FT_END_STMNT    } while ( 0 )
 #define FT_DUMMY_STMNT  FT_BEGIN_STMNT FT_END_STMNT
 
 
+  /* typeof condition taken from gnulib's `intprops.h' header file */
+#if ( __GNUC__ >= 2                         || \
+      defined( __IBM__TYPEOF__ )            || \
+      ( __SUNPRO_C >= 0x5110 && !__STDC__ ) )
+#define TYPEOF( type )  (__typeof__ (type))
+#else
+#define TYPEOF( type )  /* empty */
+#endif
+
+
 #ifdef FT_MAKE_OPTION_SINGLE_OBJECT
 
 #define FT_LOCAL( x )      static  x
diff --git a/include/config/ftheader.h b/include/config/ftheader.h
index b623629..4906bc1 100644
--- a/include/config/ftheader.h
+++ b/include/config/ftheader.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Build macros of the FreeType 2 library.                              */
 /*                                                                         */
-/*  Copyright 1996-2008, 2010, 2012, 2013 by                               */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -710,14 +710,16 @@
   /*************************************************************************
    *
    * @macro:
-   *   FT_XFREE86_H
+   *   FT_FONT_FORMATS_H
    *
    * @description:
    *   A macro used in #include statements to name the file containing the
-   *   FreeType~2 API which provides functions specific to the XFree86 and
-   *   X.Org X11 servers.
+   *   FreeType~2 API which provides functions specific to font formats.
    */
-#define FT_XFREE86_H  <ftxf86.h>
+#define FT_FONT_FORMATS_H  <ftfntfmt.h>
+
+  /* deprecated */
+#define FT_XFREE86_H  FT_FONT_FORMATS_H
 
 
   /*************************************************************************
diff --git a/include/config/ftmodule.h b/include/config/ftmodule.h
index 8a91d17..e145790 100644
--- a/include/config/ftmodule.h
+++ b/include/config/ftmodule.h
@@ -21,16 +21,4 @@
 FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class )
 FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class )
 
-/*
- * New modules in 2.4.7:
-FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class )
-FT_USE_MODULE( FT_Module_Class, psaux_module_class )
-FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )
- */
-
 /* EOF */
diff --git a/include/config/ftoption.h b/include/config/ftoption.h
index db795d3..6e8a528 100644
--- a/include/config/ftoption.h
+++ b/include/config/ftoption.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    User-selectable configuration macros (specification only).           */
 /*                                                                         */
-/*  Copyright 1996-2013 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -61,7 +61,7 @@
   /*    that are statically linked to the library at compile time.  By     */
   /*    default, this file is <config/ftmodule.h>.                         */
   /*                                                                       */
-  /*  We highly recommend using the third method whenever possible.        */
+  /* We highly recommend using the third method whenever possible.         */
   /*                                                                       */
   /*************************************************************************/
 
@@ -216,7 +216,7 @@
 
   /*************************************************************************/
   /*                                                                       */
-  /*  PNG bitmap support.                                                  */
+  /* PNG bitmap support.                                                   */
   /*                                                                       */
   /*   FreeType now handles loading color bitmap glyphs in the PNG format. */
   /*   This requires help from the external libpng library.  Uncompressed  */
@@ -230,7 +230,7 @@
 
   /*************************************************************************/
   /*                                                                       */
-  /*  HarfBuzz support.                                                    */
+  /* HarfBuzz support.                                                     */
   /*                                                                       */
   /*   FreeType uses the HarfBuzz library to improve auto-hinting of       */
   /*   OpenType fonts.  If available, many glyphs not directly addressable */
@@ -378,10 +378,6 @@
   /* The size in bytes of the render pool used by the scan-line converter  */
   /* to do all of its work.                                                */
   /*                                                                       */
-  /* This must be greater than 4KByte if you use FreeType to rasterize     */
-  /* glyphs; otherwise, you may set it to zero to avoid unnecessary        */
-  /* allocation of the render pool.                                        */
-  /*                                                                       */
 #define FT_RENDER_POOL_SIZE  16384L
 
 
@@ -435,6 +431,8 @@
   /*     af_glyph_hints_dump_points                                        */
   /*     af_glyph_hints_dump_segments                                      */
   /*     af_glyph_hints_dump_edges                                         */
+  /*     af_glyph_hints_get_num_segments                                   */
+  /*     af_glyph_hints_get_segment_offset                                 */
   /*                                                                       */
   /*   As an argument, they use another global variable:                   */
   /*                                                                       */
@@ -659,19 +657,6 @@
 
   /*************************************************************************/
   /*                                                                       */
-  /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType    */
-  /* bytecode interpreter with a huge switch statement, rather than a call */
-  /* table.  This results in smaller and faster code for a number of       */
-  /* architectures.                                                        */
-  /*                                                                       */
-  /* Note however that on some compiler/processor combinations, undefining */
-  /* this macro will generate faster, though larger, code.                 */
-  /*                                                                       */
-#define TT_CONFIG_OPTION_INTERPRETER_SWITCH
-
-
-  /*************************************************************************/
-  /*                                                                       */
   /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the        */
   /* TrueType glyph loader to use Apple's definition of how to handle      */
   /* component offsets in composite glyphs.                                */
@@ -684,7 +669,7 @@
   /* fonts will not have them.                                             */
   /*                                                                       */
   /*   http://www.microsoft.com/typography/otspec/glyf.htm                 */
-  /*   http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html                 */
+  /*   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html */
   /*                                                                       */
 #undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
 
@@ -773,6 +758,30 @@
 
   /*************************************************************************/
   /*                                                                       */
+  /* Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is      */
+  /* possible to set up the default values of the four control points that */
+  /* define the stem darkening behaviour of the (new) CFF engine.  For     */
+  /* more details please read the documentation of the                     */
+  /* `darkening-parameters' property of the cff driver module (file        */
+  /* `ftcffdrv.h'), which allows the control at run-time.                  */
+  /*                                                                       */
+  /* Do *not* undefine these macros!                                       */
+  /*                                                                       */
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1   500
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1   400
+
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2  1000
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2   275
+
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3  1667
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3   275
+
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4  2333
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4     0
+
+
+  /*************************************************************************/
+  /*                                                                       */
   /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF       */
   /* engine gets compiled into FreeType.  If defined, it is possible to    */
   /* switch between the two engines using the `hinting-engine' property of */
@@ -811,8 +820,10 @@
   /* grid.  To find out the optimal scaling and shifting value, various    */
   /* parameter combinations are tried and scored.                          */
   /*                                                                       */
-  /* This experimental option is only active if the render mode is         */
-  /* FT_RENDER_MODE_LIGHT.                                                 */
+  /* This experimental option is active only if the rendering mode is      */
+  /* FT_RENDER_MODE_LIGHT; you can switch warping on and off with the      */
+  /* `warping' property of the auto-hinter (see file `ftautoh.h' for more  */
+  /* information; by default it is switched off).                          */
   /*                                                                       */
 /* #define AF_CONFIG_OPTION_USE_WARPER */
 
@@ -820,8 +831,8 @@
 
 
   /*
-   *  This macro is obsolete.  Support has been removed in FreeType
-   *  version 2.5.
+   * This macro is obsolete.  Support has been removed in FreeType
+   * version 2.5.
    */
 /* #define FT_CONFIG_OPTION_OLD_INTERNALS */
 
@@ -837,6 +848,35 @@
 #define  TT_USE_BYTECODE_INTERPRETER
 #endif
 
+
+  /*
+   * Check CFF darkening parameters.  The checks are the same as in function
+   * `cff_property_set' in file `cffdrivr.c'.
+   */
+#if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0   || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0   || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 < 0   || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 < 0   || \
+                                                      \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 < 0   || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 < 0   || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 < 0   || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 < 0   || \
+                                                      \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 >        \
+      CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2     || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 >        \
+      CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3     || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 >        \
+      CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4     || \
+                                                      \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 > 500 || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 > 500 || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 > 500 || \
+    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 > 500
+#error "Invalid CFF darkening parameters!"
+#endif
+
 FT_END_HEADER
 
 
diff --git a/include/config/ftstdlib.h b/include/config/ftstdlib.h
index b940efc..8ef43c0 100644
--- a/include/config/ftstdlib.h
+++ b/include/config/ftstdlib.h
@@ -5,7 +5,7 @@
 /*    ANSI-specific library and header configuration file (specification   */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 2002-2007, 2009, 2011-2012 by                                */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -141,8 +141,7 @@
   /**********************************************************************/
 
 
-#define ft_atol   atol
-#define ft_labs   labs
+#define ft_atol  atol
 
 
   /**********************************************************************/
diff --git a/include/freetype.h b/include/freetype.h
index d6217e9..bca93e5 100644
--- a/include/freetype.h
+++ b/include/freetype.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType high-level API and common types (specification only).       */
 /*                                                                         */
-/*  Copyright 1996-2014 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -113,7 +113,8 @@
   /*    The FreeType~2 base font interface.                                */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    This section describes the public high-level API of FreeType~2.    */
+  /*    This section describes the most important public high-level API    */
+  /*    functions of FreeType~2.                                           */
   /*                                                                       */
   /* <Order>                                                               */
   /*    FT_Library                                                         */
@@ -122,6 +123,7 @@
   /*    FT_GlyphSlot                                                       */
   /*    FT_CharMap                                                         */
   /*    FT_Encoding                                                        */
+  /*    FT_ENC_TAG                                                         */
   /*                                                                       */
   /*    FT_FaceRec                                                         */
   /*                                                                       */
@@ -138,8 +140,22 @@
   /*    FT_FACE_FLAG_MULTIPLE_MASTERS                                      */
   /*    FT_FACE_FLAG_GLYPH_NAMES                                           */
   /*    FT_FACE_FLAG_EXTERNAL_STREAM                                       */
-  /*    FT_FACE_FLAG_FAST_GLYPHS                                           */
   /*    FT_FACE_FLAG_HINTER                                                */
+  /*    FT_FACE_FLAG_TRICKY                                                */
+  /*                                                                       */
+  /*    FT_HAS_HORIZONTAL                                                  */
+  /*    FT_HAS_VERTICAL                                                    */
+  /*    FT_HAS_KERNING                                                     */
+  /*    FT_HAS_FIXED_SIZES                                                 */
+  /*    FT_HAS_GLYPH_NAMES                                                 */
+  /*    FT_HAS_MULTIPLE_MASTERS                                            */
+  /*    FT_HAS_COLOR                                                       */
+  /*                                                                       */
+  /*    FT_IS_SFNT                                                         */
+  /*    FT_IS_SCALABLE                                                     */
+  /*    FT_IS_FIXED_WIDTH                                                  */
+  /*    FT_IS_CID_KEYED                                                    */
+  /*    FT_IS_TRICKY                                                       */
   /*                                                                       */
   /*    FT_STYLE_FLAG_BOLD                                                 */
   /*    FT_STYLE_FLAG_ITALIC                                               */
@@ -158,6 +174,7 @@
   /*                                                                       */
   /*    FT_New_Face                                                        */
   /*    FT_Done_Face                                                       */
+  /*    FT_Reference_Face                                                  */
   /*    FT_New_Memory_Face                                                 */
   /*    FT_Open_Face                                                       */
   /*    FT_Open_Args                                                       */
@@ -170,10 +187,13 @@
   /*    FT_Request_Size                                                    */
   /*    FT_Select_Size                                                     */
   /*    FT_Size_Request_Type                                               */
+  /*    FT_Size_RequestRec                                                 */
   /*    FT_Size_Request                                                    */
   /*    FT_Set_Transform                                                   */
   /*    FT_Load_Glyph                                                      */
   /*    FT_Get_Char_Index                                                  */
+  /*    FT_Get_First_Char                                                  */
+  /*    FT_Get_Next_Char                                                   */
   /*    FT_Get_Name_Index                                                  */
   /*    FT_Load_Char                                                       */
   /*                                                                       */
@@ -190,11 +210,11 @@
   /*    FT_LOAD_NO_SCALE                                                   */
   /*    FT_LOAD_NO_HINTING                                                 */
   /*    FT_LOAD_NO_BITMAP                                                  */
-  /*    FT_LOAD_CROP_BITMAP                                                */
+  /*    FT_LOAD_NO_AUTOHINT                                                */
+  /*    FT_LOAD_COLOR                                                      */
   /*                                                                       */
   /*    FT_LOAD_VERTICAL_LAYOUT                                            */
   /*    FT_LOAD_IGNORE_TRANSFORM                                           */
-  /*    FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH                                */
   /*    FT_LOAD_FORCE_AUTOHINT                                             */
   /*    FT_LOAD_NO_RECURSE                                                 */
   /*    FT_LOAD_PEDANTIC                                                   */
@@ -205,6 +225,8 @@
   /*    FT_LOAD_TARGET_LCD                                                 */
   /*    FT_LOAD_TARGET_LCD_V                                               */
   /*                                                                       */
+  /*    FT_LOAD_TARGET_MODE                                                */
+  /*                                                                       */
   /*    FT_Render_Glyph                                                    */
   /*    FT_Render_Mode                                                     */
   /*    FT_Get_Kerning                                                     */
@@ -218,14 +240,22 @@
   /*    FT_Set_Charmap                                                     */
   /*    FT_Get_Charmap_Index                                               */
   /*                                                                       */
-  /*    FT_FSTYPE_INSTALLABLE_EMBEDDING                                    */
-  /*    FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING                             */
-  /*    FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING                              */
-  /*    FT_FSTYPE_EDITABLE_EMBEDDING                                       */
-  /*    FT_FSTYPE_NO_SUBSETTING                                            */
-  /*    FT_FSTYPE_BITMAP_EMBEDDING_ONLY                                    */
-  /*                                                                       */
   /*    FT_Get_FSType_Flags                                                */
+  /*    FT_Get_SubGlyph_Info                                               */
+  /*                                                                       */
+  /*    FT_Face_Internal                                                   */
+  /*    FT_Size_Internal                                                   */
+  /*    FT_Slot_Internal                                                   */
+  /*                                                                       */
+  /*    FT_FACE_FLAG_XXX                                                   */
+  /*    FT_STYLE_FLAG_XXX                                                  */
+  /*    FT_OPEN_XXX                                                        */
+  /*    FT_LOAD_XXX                                                        */
+  /*    FT_LOAD_TARGET_XXX                                                 */
+  /*    FT_SUBGLYPH_FLAG_XXX                                               */
+  /*    FT_FSTYPE_XXX                                                      */
+  /*                                                                       */
+  /*    FT_HAS_FAST_GLYPHS                                                 */
   /*                                                                       */
   /*************************************************************************/
 
@@ -364,8 +394,11 @@
   /*    It also embeds a memory manager (see @FT_Memory), as well as a     */
   /*    scan-line converter object (see @FT_Raster).                       */
   /*                                                                       */
-  /*    In multi-threaded applications, make sure that the same FT_Library */
-  /*    object or any of its children doesn't get accessed in parallel.    */
+  /*    In multi-threaded applications it is easiest to use one            */
+  /*    `FT_Library' object per thread.  In case this is too cumbersome,   */
+  /*    a single `FT_Library' object across threads is possible also       */
+  /*    (since FreeType version 2.5.6), as long as a mutex lock is used    */
+  /*    around @FT_New_Face and @FT_Done_Face.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    Library objects are normally created by @FT_Init_FreeType, and     */
@@ -378,6 +411,13 @@
 
   /*************************************************************************/
   /*                                                                       */
+  /* <Section>                                                             */
+  /*    module_management                                                  */
+  /*                                                                       */
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
   /* <Type>                                                                */
   /*    FT_Module                                                          */
   /*                                                                       */
@@ -417,6 +457,13 @@
 
   /*************************************************************************/
   /*                                                                       */
+  /* <Section>                                                             */
+  /*    base_interface                                                     */
+  /*                                                                       */
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
   /* <Type>                                                                */
   /*    FT_Face                                                            */
   /*                                                                       */
@@ -433,6 +480,14 @@
   /*                                                                       */
   /*    Use @FT_Done_Face to destroy it (along with its slot and sizes).   */
   /*                                                                       */
+  /*    An `FT_Face' object can only be safely used from one thread at a   */
+  /*    time.  Similarly, creation and destruction of `FT_Face' with the   */
+  /*    same @FT_Library object can only be done from one thread at a      */
+  /*    time.  On the other hand, functions like @FT_Load_Glyph and its    */
+  /*    siblings are thread-safe and do not need the lock to be held as    */
+  /*    long as the same `FT_Face' object is not used from multiple        */
+  /*    threads at the same time.                                          */
+  /*                                                                       */
   /* <Also>                                                                */
   /*    See @FT_FaceRec for the publicly accessible fields of a given face */
   /*    object.                                                            */
@@ -587,9 +642,13 @@
   /*                                                                       */
   /*    FT_ENCODING_MS_SYMBOL ::                                           */
   /*      Corresponds to the Microsoft Symbol encoding, used to encode     */
-  /*      mathematical symbols in the 32..255 character code range.  For   */
-  /*      more information, see                                            */
-  /*      `http://www.kostis.net/charsets/symbol.htm'.                     */
+  /*      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'.                   */
+  /*                                                                       */
+  /*      This encoding uses character codes from the PUA (Private Unicode */
+  /*      Area) in the range U+F020-U+F0FF.                                */
   /*                                                                       */
   /*    FT_ENCODING_SJIS ::                                                */
   /*      Corresponds to Japanese SJIS encoding.  More info at             */
@@ -607,7 +666,7 @@
   /*    FT_ENCODING_WANSUNG ::                                             */
   /*      Corresponds to the Korean encoding system known as Wansung.      */
   /*      For more information see                                         */
-  /*      `http://msdn.microsoft.com/en-US/goglobal/cc305154'.             */
+  /*      `https://msdn.microsoft.com/en-US/goglobal/cc305154'.            */
   /*                                                                       */
   /*    FT_ENCODING_JOHAB ::                                               */
   /*      The Korean standard character set (KS~C 5601-1992), which        */
@@ -727,15 +786,8 @@
   } FT_Encoding;
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Enum>                                                                */
-  /*    ft_encoding_xxx                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    These constants are deprecated; use the corresponding @FT_Encoding */
-  /*    values instead.                                                    */
-  /*                                                                       */
+  /* these constants are deprecated; use the corresponding `FT_Encoding' */
+  /* values instead                                                      */
 #define ft_encoding_none            FT_ENCODING_NONE
 #define ft_encoding_unicode         FT_ENCODING_UNICODE
 #define ft_encoding_symbol          FT_ENCODING_MS_SYMBOL
@@ -856,6 +908,11 @@
   /*                           Can be NULL (e.g., in fonts embedded in a   */
   /*                           PDF file).                                  */
   /*                                                                       */
+  /*                           In case the font doesn't provide a specific */
+  /*                           family name entry, FreeType tries to        */
+  /*                           synthesize one, deriving it from other name */
+  /*                           entries.                                    */
+  /*                                                                       */
   /*    style_name          :: The face's style name.  This is an ASCII    */
   /*                           string, usually in English, that describes  */
   /*                           the typeface's style (like `Italic',        */
@@ -1103,7 +1160,7 @@
   /*      TrueType bytecode instructions to move and scale all of its      */
   /*      subglyphs.                                                       */
   /*                                                                       */
-  /*      It is not possible to autohint such fonts using                  */
+  /*      It is not possible to auto-hint such fonts using                 */
   /*      @FT_LOAD_FORCE_AUTOHINT; it will also ignore                     */
   /*      @FT_LOAD_NO_HINTING.  You have to set both @FT_LOAD_NO_HINTING   */
   /*      and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */
@@ -1570,15 +1627,15 @@
   /*                         change between calls of @FT_Load_Glyph and a  */
   /*                         few other functions.                          */
   /*                                                                       */
-  /*    bitmap_left       :: This is the bitmap's left bearing expressed   */
-  /*                         in integer pixels.  Of course, this is only   */
-  /*                         valid if the format is                        */
-  /*                         @FT_GLYPH_FORMAT_BITMAP.                      */
+  /*    bitmap_left       :: The bitmap's left bearing expressed in        */
+  /*                         integer pixels.  Only valid if the format is  */
+  /*                         @FT_GLYPH_FORMAT_BITMAP, this is, if the      */
+  /*                         glyph slot contains a bitmap.                 */
   /*                                                                       */
-  /*    bitmap_top        :: This is 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   */
+  /*    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*.                                   */
   /*                                                                       */
   /*    outline           :: The outline descriptor for the current glyph  */
@@ -1612,11 +1669,11 @@
   /*                         needs to know about the image format.         */
   /*                                                                       */
   /*    lsb_delta         :: The difference between hinted and unhinted    */
-  /*                         left side bearing while autohinting is        */
+  /*                         left side bearing while auto-hinting is       */
   /*                         active.  Zero otherwise.                      */
   /*                                                                       */
   /*    rsb_delta         :: The difference between hinted and unhinted    */
-  /*                         right side bearing while autohinting is       */
+  /*                         right side bearing while auto-hinting is      */
   /*                         active.  Zero otherwise.                      */
   /*                                                                       */
   /* <Note>                                                                */
@@ -1639,7 +1696,7 @@
   /*    `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP.         */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    Here a small pseudo code fragment that shows how to use            */
+  /*    Here is a small pseudo code fragment that shows how to use         */
   /*    `lsb_delta' and `rsb_delta':                                       */
   /*                                                                       */
   /*    {                                                                  */
@@ -1732,8 +1789,8 @@
   /*    use @FT_New_Library instead, followed by a call to                 */
   /*    @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module).  */
   /*                                                                       */
-  /*    For multi-threading applications each thread should have its own   */
-  /*    FT_Library object.                                                 */
+  /*    See the documentation of @FT_Library and @FT_Face for              */
+  /*    multi-threading issues.                                            */
   /*                                                                       */
   /*    If you need reference-counting (cf. @FT_Reference_Library), use    */
   /*    @FT_New_Library and @FT_Done_Library.                              */
@@ -1782,16 +1839,6 @@
   /*                                                                       */
   /*    FT_OPEN_PARAMS   :: Use the `num_params' and `params' fields.      */
   /*                                                                       */
-  /*    ft_open_memory   :: Deprecated; use @FT_OPEN_MEMORY instead.       */
-  /*                                                                       */
-  /*    ft_open_stream   :: Deprecated; use @FT_OPEN_STREAM instead.       */
-  /*                                                                       */
-  /*    ft_open_pathname :: Deprecated; use @FT_OPEN_PATHNAME instead.     */
-  /*                                                                       */
-  /*    ft_open_driver   :: Deprecated; use @FT_OPEN_DRIVER instead.       */
-  /*                                                                       */
-  /*    ft_open_params   :: Deprecated; use @FT_OPEN_PARAMS instead.       */
-  /*                                                                       */
   /* <Note>                                                                */
   /*    The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME'     */
   /*    flags are mutually exclusive.                                      */
@@ -1802,11 +1849,14 @@
 #define FT_OPEN_DRIVER    0x8
 #define FT_OPEN_PARAMS    0x10
 
-#define ft_open_memory    FT_OPEN_MEMORY     /* deprecated */
-#define ft_open_stream    FT_OPEN_STREAM     /* deprecated */
-#define ft_open_pathname  FT_OPEN_PATHNAME   /* deprecated */
-#define ft_open_driver    FT_OPEN_DRIVER     /* deprecated */
-#define ft_open_params    FT_OPEN_PARAMS     /* deprecated */
+
+  /* these constants are deprecated; use the corresponding `FT_OPEN_XXX' */
+  /* values instead                                                      */
+#define ft_open_memory    FT_OPEN_MEMORY
+#define ft_open_stream    FT_OPEN_STREAM
+#define ft_open_pathname  FT_OPEN_PATHNAME
+#define ft_open_driver    FT_OPEN_DRIVER
+#define ft_open_params    FT_OPEN_PARAMS
 
 
   /*************************************************************************/
@@ -1871,22 +1921,22 @@
   /*    The stream type is determined by the contents of `flags' that      */
   /*    are tested in the following order by @FT_Open_Face:                */
   /*                                                                       */
-  /*    If the `FT_OPEN_MEMORY' bit is set, assume that this is a          */
+  /*    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     */
   /*    releasing and destroying them _after_ the corresponding call to    */
   /*    @FT_Done_Face.                                                     */
   /*                                                                       */
-  /*    Otherwise, if the `FT_OPEN_STREAM' bit is set, assume that a       */
+  /*    Otherwise, if the @FT_OPEN_STREAM bit is set, assume that a        */
   /*    custom input stream `stream' is used.                              */
   /*                                                                       */
-  /*    Otherwise, if the `FT_OPEN_PATHNAME' bit is set, assume that this  */
+  /*    Otherwise, if the @FT_OPEN_PATHNAME bit is set, assume that this   */
   /*    is a normal file and use `pathname' to open it.                    */
   /*                                                                       */
-  /*    If the `FT_OPEN_DRIVER' bit is set, @FT_Open_Face only tries to    */
+  /*    If the @FT_OPEN_DRIVER bit is set, @FT_Open_Face only tries to     */
   /*    open the file with the driver whose handler is in `driver'.        */
   /*                                                                       */
-  /*    If the `FT_OPEN_PARAMS' bit is set, the parameters given by        */
+  /*    If the @FT_OPEN_PARAMS bit is set, the parameters given by         */
   /*    `num_params' and `params' is used.  They are ignored otherwise.    */
   /*                                                                       */
   /*    Ideally, both the `pathname' and `params' fields should be tagged  */
@@ -2540,11 +2590,6 @@
    *     Indicates that the auto-hinter is preferred over the font's native
    *     hinter.  See also the note below.
    *
-   *   FT_LOAD_CROP_BITMAP ::
-   *     Indicates that the font driver should crop the loaded bitmap glyph
-   *     (i.e., remove all space around its black bits).  Not all drivers
-   *     implement this.
-   *
    *   FT_LOAD_PEDANTIC ::
    *     Indicates that the font driver should perform pedantic verifications
    *     during glyph loading.  This is mostly used to detect broken glyphs
@@ -2555,9 +2600,6 @@
    *     result in partially hinted or distorted glyphs in case a glyph's
    *     bytecode is buggy.
    *
-   *   FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ::
-   *     Ignored.  Deprecated.
-   *
    *   FT_LOAD_NO_RECURSE ::
    *     Indicate that the font driver should not load composite glyphs
    *     recursively.  Instead, it should set the `num_subglyph' and
@@ -2596,6 +2638,12 @@
    *     bitmaps transparently.  Those bitmaps will be in the
    *     @FT_PIXEL_MODE_GRAY format.
    *
+   *   FT_LOAD_CROP_BITMAP ::
+   *     Ignored.  Deprecated.
+   *
+   *   FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ::
+   *     Ignored.  Deprecated.
+   *
    * @note:
    *   By default, hinting is enabled and the font's native hinter (see
    *   @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter.  You can
@@ -2832,19 +2880,8 @@
   } FT_Render_Mode;
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Enum>                                                                */
-  /*    ft_render_mode_xxx                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    These constants are deprecated.  Use the corresponding             */
-  /*    @FT_Render_Mode values instead.                                    */
-  /*                                                                       */
-  /* <Values>                                                              */
-  /*    ft_render_mode_normal :: see @FT_RENDER_MODE_NORMAL                */
-  /*    ft_render_mode_mono   :: see @FT_RENDER_MODE_MONO                  */
-  /*                                                                       */
+  /* these constants are deprecated; use the corresponding */
+  /* `FT_Render_Mode' values instead                       */
 #define ft_render_mode_normal  FT_RENDER_MODE_NORMAL
 #define ft_render_mode_mono    FT_RENDER_MODE_MONO
 
@@ -2908,39 +2945,10 @@
   } FT_Kerning_Mode;
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Const>                                                               */
-  /*    ft_kerning_default                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    This constant is deprecated.  Please use @FT_KERNING_DEFAULT       */
-  /*    instead.                                                           */
-  /*                                                                       */
+  /* these constants are deprecated; use the corresponding */
+  /* `FT_Kerning_Mode' values instead                      */
 #define ft_kerning_default   FT_KERNING_DEFAULT
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Const>                                                               */
-  /*    ft_kerning_unfitted                                                */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    This constant is deprecated.  Please use @FT_KERNING_UNFITTED      */
-  /*    instead.                                                           */
-  /*                                                                       */
 #define ft_kerning_unfitted  FT_KERNING_UNFITTED
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Const>                                                               */
-  /*    ft_kerning_unscaled                                                */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    This constant is deprecated.  Please use @FT_KERNING_UNSCALED      */
-  /*    instead.                                                           */
-  /*                                                                       */
 #define ft_kerning_unscaled  FT_KERNING_UNSCALED
 
 
@@ -3410,8 +3418,9 @@
   /*    @FT_Get_FSType_Flags; they inform client applications of embedding */
   /*    and subsetting restrictions associated with a font.                */
   /*                                                                       */
-  /*    See http://www.adobe.com/devnet/acrobat/pdfs/FontPolicies.pdf for  */
-  /*    more details.                                                      */
+  /*    See                                                                */
+  /*    http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/FontPolicies.pdf */
+  /*    for more details.                                                  */
   /*                                                                       */
   /* <Values>                                                              */
   /*    FT_FSTYPE_INSTALLABLE_EMBEDDING ::                                 */
@@ -3510,8 +3519,8 @@
   /*                                                                       */
   /*      http://www.unicode.org/reports/tr37/                             */
   /*                                                                       */
-  /*    To date (November 2012), the character with the most variants is   */
-  /*    U+9089, having 31 such IVS.                                        */
+  /*    To date (November 2014), 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       */
   /*    (format~14).  It is an odd subtable because it is not a mapping of */
@@ -3762,12 +3771,6 @@
              FT_Long  c );
 
 
-  /* */
-
-  /* The following #if 0 ... #endif is for the documentation formatter, */
-  /* hiding the internal `FT_MULFIX_INLINED' macro.                     */
-
-#if 0
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -3801,17 +3804,6 @@
   FT_MulFix( FT_Long  a,
              FT_Long  b );
 
-  /* */
-#endif
-
-#ifdef FT_MULFIX_INLINED
-#define FT_MulFix( a, b )  FT_MULFIX_INLINED( a, b )
-#else
-  FT_EXPORT( FT_Long )
-  FT_MulFix( FT_Long  a,
-             FT_Long  b );
-#endif
-
 
   /*************************************************************************/
   /*                                                                       */
@@ -3824,18 +3816,12 @@
   /*    used to divide 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).                                    */
+  /*    a :: The numerator.                                                */
+  /*    b :: The denominator.  Use a 16.16 factor here.                    */
   /*                                                                       */
   /* <Return>                                                              */
   /*    The result of `(a*0x10000)/b'.                                     */
   /*                                                                       */
-  /* <Note>                                                                */
-  /*    The optimization for FT_DivFix() is simple: If (a~<<~16) fits in   */
-  /*    32~bits, then the division is computed directly.  Otherwise, we    */
-  /*    use a specialized version of @FT_MulDiv.                           */
-  /*                                                                       */
   FT_EXPORT( FT_Long )
   FT_DivFix( FT_Long  a,
              FT_Long  b );
@@ -3935,6 +3921,18 @@
   /*    even a new release of FreeType with only documentation changes     */
   /*    increases the version number.                                      */
   /*                                                                       */
+  /* <Order>                                                               */
+  /*    FT_Library_Version                                                 */
+  /*                                                                       */
+  /*    FREETYPE_MAJOR                                                     */
+  /*    FREETYPE_MINOR                                                     */
+  /*    FREETYPE_PATCH                                                     */
+  /*                                                                       */
+  /*    FT_Face_CheckTrueTypePatents                                       */
+  /*    FT_Face_SetUnpatentedHinting                                       */
+  /*                                                                       */
+  /*    FREETYPE_XXX                                                       */
+  /*                                                                       */
   /*************************************************************************/
 
 
@@ -3959,8 +3957,8 @@
    *
    */
 #define FREETYPE_MAJOR  2
-#define FREETYPE_MINOR  5
-#define FREETYPE_PATCH  3
+#define FREETYPE_MINOR  6
+#define FREETYPE_PATCH  0
 
 
   /*************************************************************************/
diff --git a/include/ft2build.h b/include/ft2build.h
index 6f8eb7f..09c19d4 100644
--- a/include/ft2build.h
+++ b/include/ft2build.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType 2 build and setup macros.                                   */
 /*                                                                         */
-/*  Copyright 1996-2001, 2006, 2013 by                                     */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/ftadvanc.h b/include/ftadvanc.h
index 8f7e2fc..b4d2aed 100644
--- a/include/ftadvanc.h
+++ b/include/ftadvanc.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Quick computation of advance widths (specification only).            */
 /*                                                                         */
-/*  Copyright 2008, 2013 by                                                */
+/*  Copyright 2008-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -48,6 +48,11 @@
    * @description:
    *   This section contains functions to quickly extract advance values
    *   without handling glyph outlines, if possible.
+   *
+   * @order:
+   *   FT_Get_Advance
+   *   FT_Get_Advances
+   *
    */
 
 
@@ -72,7 +77,7 @@
   /*    and hinting of the glyph outline, are extremely slow by            */
   /*    comparison.                                                        */
   /*                                                                       */
-#define FT_ADVANCE_FLAG_FAST_ONLY  0x20000000UL
+#define FT_ADVANCE_FLAG_FAST_ONLY  0x20000000L
 
 
   /*************************************************************************/
@@ -171,7 +176,7 @@
                    FT_Int32   load_flags,
                    FT_Fixed  *padvances );
 
-/* */
+  /* */
 
 
 FT_END_HEADER
diff --git a/include/ftautoh.h b/include/ftautoh.h
index 936791e..cf7b76f 100644
--- a/include/ftautoh.h
+++ b/include/ftautoh.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for controlling the auto-hinter (specification only).   */
 /*                                                                         */
-/*  Copyright 2012, 2013 by                                                */
+/*  Copyright 2012-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -245,12 +245,12 @@
    *   The data exchange structure for the @glyph-to-script-map property.
    *
    */
-   typedef struct  FT_Prop_GlyphToScriptMap_
-   {
-     FT_Face   face;
-     FT_Byte*  map;
+  typedef struct  FT_Prop_GlyphToScriptMap_
+  {
+    FT_Face   face;
+    FT_Byte*  map;
 
-   } FT_Prop_GlyphToScriptMap;
+  } FT_Prop_GlyphToScriptMap;
 
 
   /**************************************************************************
@@ -300,7 +300,7 @@
    * @description:
    *   *Experimental* *only*
    *
-   *   If Freetype gets compiled with FT_CONFIG_OPTION_USE_HARFBUZZ to make
+   *   If FreeType gets compiled with FT_CONFIG_OPTION_USE_HARFBUZZ to make
    *   the HarfBuzz library access OpenType features for getting better
    *   glyph coverages, this property sets the (auto-fitter) script to be
    *   used for the default (OpenType) script data of a font's GSUB table.
@@ -384,15 +384,63 @@
    *   The data exchange structure for the @increase-x-height property.
    *
    */
-   typedef struct  FT_Prop_IncreaseXHeight_
-   {
-     FT_Face  face;
-     FT_UInt  limit;
+  typedef struct  FT_Prop_IncreaseXHeight_
+  {
+    FT_Face  face;
+    FT_UInt  limit;
 
-   } FT_Prop_IncreaseXHeight;
+  } FT_Prop_IncreaseXHeight;
 
 
- /* */
+  /**************************************************************************
+   *
+   * @property:
+   *   warping
+   *
+   * @description:
+   *   *Experimental* *only*
+   *
+   *   If FreeType gets compiled with option AF_CONFIG_OPTION_USE_WARPER to
+   *   activate the warp hinting code in the auto-hinter, this property
+   *   switches warping on and off.
+   *
+   *   Warping only works in `light' auto-hinting mode.  The idea of the
+   *   code is to slightly scale and shift a glyph along the non-hinted
+   *   dimension (which is usually the horizontal axis) so that as much of
+   *   its segments are aligned (more or less) to the grid.  To find out a
+   *   glyph's optimal scaling and shifting value, various parameter
+   *   combinations are tried and scored.
+   *
+   *   By default, warping is off.  The example below shows how to switch on
+   *   warping (omitting the error handling).
+   *
+   *   {
+   *     FT_Library  library;
+   *     FT_Bool     warping = 1;
+   *
+   *
+   *     FT_Init_FreeType( &library );
+   *
+   *     FT_Property_Set( library, "autofitter",
+   *                               "warping", &warping );
+   *   }
+   *
+   * @note:
+   *   This property can be used with @FT_Property_Get also.
+   *
+   *   The warping code can also change advance widths.  Have a look at the
+   *   `lsb_delta' and `rsb_delta' fields in the @FT_GlyphSlotRec structure
+   *   for details on improving inter-glyph distances while rendering.
+   *
+   *   Since warping is a global property of the auto-hinter it is best to
+   *   change its value before rendering any face.  Otherwise, you should
+   *   reload all faces that get auto-hinted in `light' hinting mode.
+   *
+   */
+
+
+  /* */
+
 
 FT_END_HEADER
 
diff --git a/include/ftbbox.h b/include/ftbbox.h
index 8938841..9d9d040 100644
--- a/include/ftbbox.h
+++ b/include/ftbbox.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType exact bbox computation (specification).                     */
 /*                                                                         */
-/*  Copyright 1996-2001, 2003, 2007, 2011, 2013 by                         */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -85,7 +85,6 @@
   FT_Outline_Get_BBox( FT_Outline*  outline,
                        FT_BBox     *abbox );
 
-
   /* */
 
 
diff --git a/include/ftbdf.h b/include/ftbdf.h
index 8b3c411..0bdabf4 100644
--- a/include/ftbdf.h
+++ b/include/ftbdf.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for accessing BDF-specific strings (specification).     */
 /*                                                                         */
-/*  Copyright 2002-2004, 2006, 2009, 2014 by                               */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -53,7 +53,7 @@
   /**********************************************************************
    *
    * @enum:
-   *    FT_PropertyType
+   *    BDF_PropertyType
    *
    * @description:
    *    A list of BDF property types.
@@ -200,7 +200,7 @@
                        const char*       prop_name,
                        BDF_PropertyRec  *aproperty );
 
- /* */
+  /* */
 
 FT_END_HEADER
 
diff --git a/include/ftbitmap.h b/include/ftbitmap.h
index 7dbf5ba..46cc47b 100644
--- a/include/ftbitmap.h
+++ b/include/ftbitmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility functions for bitmaps (specification).              */
 /*                                                                         */
-/*  Copyright 2004-2006, 2008, 2013 by                                     */
+/*  Copyright 2004-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -45,7 +45,9 @@
   /*    Handling FT_Bitmap objects.                                        */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    This section contains functions for converting FT_Bitmap objects.  */
+  /*    This section contains functions for handling @FT_Bitmap objects.   */
+  /*    Note that none of the functions changes the bitmap's `flow' (as    */
+  /*    indicated by the sign of the `pitch' field in `FT_Bitmap').        */
   /*                                                                       */
   /*************************************************************************/
 
@@ -53,7 +55,7 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    FT_Bitmap_New                                                      */
+  /*    FT_Bitmap_Init                                                     */
   /*                                                                       */
   /* <Description>                                                         */
   /*    Initialize a pointer to an @FT_Bitmap structure.                   */
@@ -61,6 +63,14 @@
   /* <InOut>                                                               */
   /*    abitmap :: A pointer to the bitmap structure.                      */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    A deprecated name for the same function is `FT_Bitmap_New'.        */
+  /*                                                                       */
+  FT_EXPORT( void )
+  FT_Bitmap_Init( FT_Bitmap  *abitmap );
+
+
+  /* deprecated */
   FT_EXPORT( void )
   FT_Bitmap_New( FT_Bitmap  *abitmap );
 
@@ -122,6 +132,9 @@
   /*    If you want to embolden the bitmap owned by a @FT_GlyphSlotRec,    */
   /*    you should call @FT_GlyphSlot_Own_Bitmap on the slot first.        */
   /*                                                                       */
+  /*    Bitmaps in @FT_PIXEL_MODE_GRAY2 and @FT_PIXEL_MODE_GRAY@ format    */
+  /*    are converted to @FT_PIXEL_MODE_GRAY format (i.e., 8bpp).          */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Bitmap_Embolden( FT_Library  library,
                       FT_Bitmap*  bitmap,
@@ -197,7 +210,7 @@
   /*    FT_Bitmap_Done                                                     */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Destroy a bitmap object created with @FT_Bitmap_New.               */
+  /*    Destroy a bitmap object initialized with @FT_Bitmap_Init.          */
   /*                                                                       */
   /* <Input>                                                               */
   /*    library :: A handle to a library object.                           */
diff --git a/include/ftbzip2.h b/include/ftbzip2.h
index 1bf81b1..c25f946 100644
--- a/include/ftbzip2.h
+++ b/include/ftbzip2.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Bzip2-compressed stream support.                                     */
 /*                                                                         */
-/*  Copyright 2010 by                                                      */
+/*  Copyright 2010-2015 by                                                 */
 /*  Joel Klinghed.                                                         */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -91,7 +91,7 @@
   FT_Stream_OpenBzip2( FT_Stream  stream,
                        FT_Stream  source );
 
- /* */
+  /* */
 
 
 FT_END_HEADER
diff --git a/include/ftcache.h b/include/ftcache.h
index a5d7100..68525bb 100644
--- a/include/ftcache.h
+++ b/include/ftcache.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType Cache subsystem (specification).                            */
 /*                                                                         */
-/*  Copyright 1996-2008, 2010, 2013 by                                     */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -209,10 +209,10 @@
   typedef FT_Error
   (*FTC_Face_Requester)( FTC_FaceID  face_id,
                          FT_Library  library,
-                         FT_Pointer  request_data,
+                         FT_Pointer  req_data,
                          FT_Face*    aface );
 
- /* */
+  /* */
 
 
   /*************************************************************************/
@@ -667,8 +667,8 @@
   typedef struct  FTC_ImageTypeRec_
   {
     FTC_FaceID  face_id;
-    FT_Int      width;
-    FT_Int      height;
+    FT_UInt     width;
+    FT_UInt     height;
     FT_Int32    flags;
 
   } FTC_ImageTypeRec;
@@ -1046,8 +1046,8 @@
                               FTC_SBit      *sbit,
                               FTC_Node      *anode );
 
+  /* */
 
- /* */
 
 FT_END_HEADER
 
diff --git a/include/ftcffdrv.h b/include/ftcffdrv.h
index e4d039d..6c8e416 100644
--- a/include/ftcffdrv.h
+++ b/include/ftcffdrv.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for controlling the CFF driver (specification only).    */
 /*                                                                         */
-/*  Copyright 2013 by                                                      */
+/*  Copyright 2013-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -108,6 +108,12 @@
    *   in one of four ways, top edge up or down, bottom edge up or down.
    *   Unless there are conflicting hstems, the smallest movement is taken
    *   to minimize distortion.
+   *
+   * @order:
+   *   hinting-engine
+   *   no-stem-darkening
+   *   darkening-parameters
+   *
    */
 
 
@@ -212,9 +218,11 @@
    *     stem width >= 2.333px: darkening amount = 0px
    *   }
    *
-   *   and piecewise linear in-between.  Using the `darkening-parameters'
-   *   property, these four control points can be changed, as the following
-   *   example demonstrates.
+   *   and piecewise linear in-between.  At configuration time, these four
+   *   control points can be set with the macro
+   *   `CFF_CONFIG_OPTION_DARKENING_PARAMETERS'.  At runtime, the control
+   *   points can be changed using the `darkening-parameters' property, as
+   *   the following example demonstrates.
    *
    *   {
    *     FT_Library  library;
@@ -242,8 +250,8 @@
    *
    */
 
+  /* */
 
- /* */
 
 FT_END_HEADER
 
diff --git a/include/ftcid.h b/include/ftcid.h
index 203a30c..05741c8 100644
--- a/include/ftcid.h
+++ b/include/ftcid.h
@@ -4,7 +4,8 @@
 /*                                                                         */
 /*    FreeType API for accessing CID font information (specification).     */
 /*                                                                         */
-/*  Copyright 2007, 2009 by Dereg Clegg, Michael Toftdal.                  */
+/*  Copyright 2007-2015 by                                                 */
+/*  Dereg Clegg and Michael Toftdal.                                       */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
 /*  modified, and distributed under the terms of the FreeType project      */
@@ -156,7 +157,8 @@
                                FT_UInt   glyph_index,
                                FT_UInt  *cid );
 
- /* */
+  /* */
+
 
 FT_END_HEADER
 
diff --git a/include/fterrdef.h b/include/fterrdef.h
index 99b2fad..1bf0751 100644
--- a/include/fterrdef.h
+++ b/include/fterrdef.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType error codes (specification).                                */
 /*                                                                         */
-/*  Copyright 2002, 2004, 2006, 2007, 2010-2013 by                         */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/fterrors.h b/include/fterrors.h
index 0fa3e4d..376bee6 100644
--- a/include/fterrors.h
+++ b/include/fterrors.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType error code handling (specification).                        */
 /*                                                                         */
-/*  Copyright 1996-2002, 2004, 2007, 2013 by                               */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/ftxf86.h b/include/ftfntfmt.h
similarity index 79%
rename from include/ftxf86.h
rename to include/ftfntfmt.h
index 493cccd..1f8ff28 100644
--- a/include/ftxf86.h
+++ b/include/ftfntfmt.h
@@ -1,10 +1,10 @@
 /***************************************************************************/
 /*                                                                         */
-/*  ftxf86.h                                                               */
+/*  ftfntfmt.h                                                             */
 /*                                                                         */
-/*    Support functions for X11.                                           */
+/*    Support functions for font formats.                                  */
 /*                                                                         */
-/*  Copyright 2002-2004, 2006, 2007, 2013 by                               */
+/*  Copyright 2002-2015 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 __FTXF86_H__
-#define __FTXF86_H__
+#ifndef __FTFNTFMT_H__
+#define __FTFNTFMT_H__
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
@@ -49,22 +49,20 @@
   /*   however, there are special cases (like in PDF devices) where it is  */
   /*   important to differentiate, in spite of FreeType's uniform API.     */
   /*                                                                       */
-  /*   This function is in the X11/xf86 namespace for historical reasons   */
-  /*   and in no way depends on that windowing system.                     */
-  /*                                                                       */
   /*************************************************************************/
 
 
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*   FT_Get_X11_Font_Format                                              */
+  /*   FT_Get_Font_Format                                                  */
   /*                                                                       */
   /* <Description>                                                         */
-  /*   Return a string describing the format of a given face, using values */
-  /*   that can be used as an X11 FONT_PROPERTY.  Possible values are      */
-  /*   `TrueType', `Type~1', `BDF', `PCF', `Type~42', `CID~Type~1', `CFF', */
-  /*   `PFR', and `Windows~FNT'.                                           */
+  /*   Return a string describing the format of a given face.  Possible    */
+  /*   values are `TrueType', `Type~1', `BDF', `PCF', `Type~42',           */
+  /*   `CID~Type~1', `CFF', `PFR', and `Windows~FNT'.                      */
+  /*                                                                       */
+  /*   The return value is suitable to be used as an X11 FONT_PROPERTY.    */
   /*                                                                       */
   /* <Input>                                                               */
   /*   face ::                                                             */
@@ -73,11 +71,22 @@
   /* <Return>                                                              */
   /*   Font format string.  NULL in case of error.                         */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*   A deprecated name for the same function is                          */
+  /*   `FT_Get_X11_Font_Format'.                                           */
+  /*                                                                       */
+  FT_EXPORT( const char* )
+  FT_Get_Font_Format( FT_Face  face );
+
+
+  /* deprecated */
   FT_EXPORT( const char* )
   FT_Get_X11_Font_Format( FT_Face  face );
 
- /* */
+
+  /* */
+
 
 FT_END_HEADER
 
-#endif /* __FTXF86_H__ */
+#endif /* __FTFNTFMT_H__ */
diff --git a/include/ftgasp.h b/include/ftgasp.h
index 453d4fa..9a9b632 100644
--- a/include/ftgasp.h
+++ b/include/ftgasp.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Access of TrueType's `gasp' table (specification).                   */
 /*                                                                         */
-/*  Copyright 2007, 2008, 2011 by                                          */
+/*  Copyright 2007-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -120,7 +120,8 @@
   FT_Get_Gasp( FT_Face  face,
                FT_UInt  ppem );
 
-/* */
+  /* */
+
 
 #endif /* _FT_GASP_H_ */
 
diff --git a/include/ftglyph.h b/include/ftglyph.h
index 2d30ed9..803ad39 100644
--- a/include/ftglyph.h
+++ b/include/ftglyph.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType convenience functions to handle glyphs (specification).     */
 /*                                                                         */
-/*  Copyright 1996-2003, 2006, 2008, 2009, 2011, 2013 by                   */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -325,22 +325,8 @@
   } FT_Glyph_BBox_Mode;
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Enum>                                                                */
-  /*    ft_glyph_bbox_xxx                                                  */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    These constants are deprecated.  Use the corresponding             */
-  /*    @FT_Glyph_BBox_Mode values instead.                                */
-  /*                                                                       */
-  /* <Values>                                                              */
-  /*   ft_glyph_bbox_unscaled  :: See @FT_GLYPH_BBOX_UNSCALED.             */
-  /*   ft_glyph_bbox_subpixels :: See @FT_GLYPH_BBOX_SUBPIXELS.            */
-  /*   ft_glyph_bbox_gridfit   :: See @FT_GLYPH_BBOX_GRIDFIT.              */
-  /*   ft_glyph_bbox_truncate  :: See @FT_GLYPH_BBOX_TRUNCATE.             */
-  /*   ft_glyph_bbox_pixels    :: See @FT_GLYPH_BBOX_PIXELS.               */
-  /*                                                                       */
+  /* these constants are deprecated; use the corresponding */
+  /* `FT_Glyph_BBox_Mode' values instead                   */
 #define ft_glyph_bbox_unscaled   FT_GLYPH_BBOX_UNSCALED
 #define ft_glyph_bbox_subpixels  FT_GLYPH_BBOX_SUBPIXELS
 #define ft_glyph_bbox_gridfit    FT_GLYPH_BBOX_GRIDFIT
@@ -603,7 +589,6 @@
   FT_EXPORT( FT_Error )
   FT_Matrix_Invert( FT_Matrix*  matrix );
 
-
   /* */
 
 
diff --git a/include/ftgxval.h b/include/ftgxval.h
index 6d38e32..0e9ac1d 100644
--- a/include/ftgxval.h
+++ b/include/ftgxval.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for validating TrueTypeGX/AAT tables (specification).   */
 /*                                                                         */
-/*  Copyright 2004-2006, 2013 by                                           */
+/*  Copyright 2004-2015 by                                                 */
 /*  Masatake YAMATO, Redhat K.K,                                           */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
@@ -57,9 +57,19 @@
   /*    some TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd,  */
   /*    trak, prop, lcar).                                                 */
   /*                                                                       */
+  /* <Order>                                                               */
+  /*    FT_TrueTypeGX_Validate                                             */
+  /*    FT_TrueTypeGX_Free                                                 */
+  /*                                                                       */
+  /*    FT_ClassicKern_Validate                                            */
+  /*    FT_ClassicKern_Free                                                */
+  /*                                                                       */
+  /*    FT_VALIDATE_GX_LENGTH                                              */
+  /*    FT_VALIDATE_GXXXX                                                  */
+  /*    FT_VALIDATE_CKERNXXX                                               */
+  /*                                                                       */
   /*************************************************************************/
 
-
   /*************************************************************************/
   /*                                                                       */
   /*                                                                       */
@@ -171,8 +181,6 @@
                           FT_VALIDATE_lcar )
 
 
-  /* */
-
  /**********************************************************************
   *
   * @function:
@@ -221,8 +229,6 @@
                           FT_UInt   table_length );
 
 
-  /* */
-
  /**********************************************************************
   *
   * @function:
@@ -248,8 +254,6 @@
                       FT_Bytes  table );
 
 
-  /* */
-
  /**********************************************************************
   *
   * @enum:
@@ -277,8 +281,6 @@
 #define FT_VALIDATE_CKERN  ( FT_VALIDATE_MS | FT_VALIDATE_APPLE )
 
 
-  /* */
-
  /**********************************************************************
   *
   * @function:
@@ -320,8 +322,6 @@
                            FT_Bytes  *ckern_table );
 
 
-  /* */
-
  /**********************************************************************
   *
   * @function:
@@ -346,8 +346,7 @@
   FT_ClassicKern_Free( FT_Face   face,
                        FT_Bytes  table );
 
-
- /* */
+  /* */
 
 
 FT_END_HEADER
diff --git a/include/ftgzip.h b/include/ftgzip.h
index 78e7269..b3a532d 100644
--- a/include/ftgzip.h
+++ b/include/ftgzip.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Gzip-compressed stream support.                                      */
 /*                                                                         */
-/*  Copyright 2002-2004, 2006, 2013 by                                     */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -137,8 +137,7 @@
                       const FT_Byte*  input,
                       FT_ULong        input_len );
 
-
- /* */
+  /* */
 
 
 FT_END_HEADER
diff --git a/include/ftimage.h b/include/ftimage.h
index ea71a78..82f284c 100644
--- a/include/ftimage.h
+++ b/include/ftimage.h
@@ -5,7 +5,7 @@
 /*    FreeType glyph image formats and default raster interface            */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 1996-2010, 2013 by                                           */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -193,67 +193,14 @@
   } FT_Pixel_Mode;
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Enum>                                                                */
-  /*    ft_pixel_mode_xxx                                                  */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A list of deprecated constants.  Use the corresponding             */
-  /*    @FT_Pixel_Mode values instead.                                     */
-  /*                                                                       */
-  /* <Values>                                                              */
-  /*    ft_pixel_mode_none  :: See @FT_PIXEL_MODE_NONE.                    */
-  /*    ft_pixel_mode_mono  :: See @FT_PIXEL_MODE_MONO.                    */
-  /*    ft_pixel_mode_grays :: See @FT_PIXEL_MODE_GRAY.                    */
-  /*    ft_pixel_mode_pal2  :: See @FT_PIXEL_MODE_GRAY2.                   */
-  /*    ft_pixel_mode_pal4  :: See @FT_PIXEL_MODE_GRAY4.                   */
-  /*                                                                       */
+  /* these constants are deprecated; use the corresponding `FT_Pixel_Mode' */
+  /* values instead.                                                       */
 #define ft_pixel_mode_none   FT_PIXEL_MODE_NONE
 #define ft_pixel_mode_mono   FT_PIXEL_MODE_MONO
 #define ft_pixel_mode_grays  FT_PIXEL_MODE_GRAY
 #define ft_pixel_mode_pal2   FT_PIXEL_MODE_GRAY2
 #define ft_pixel_mode_pal4   FT_PIXEL_MODE_GRAY4
 
- /* */
-
-#if 0
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Enum>                                                                */
-  /*    FT_Palette_Mode                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    THIS TYPE IS DEPRECATED.  DO NOT USE IT!                           */
-  /*                                                                       */
-  /*    An enumeration type to describe the format of a bitmap palette,    */
-  /*    used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8.               */
-  /*                                                                       */
-  /* <Values>                                                              */
-  /*    ft_palette_mode_rgb  :: The palette is an array of 3-byte RGB      */
-  /*                            records.                                   */
-  /*                                                                       */
-  /*    ft_palette_mode_rgba :: The palette is an array of 4-byte RGBA     */
-  /*                            records.                                   */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    As ft_pixel_mode_pal2, pal4 and pal8 are currently unused by       */
-  /*    FreeType, these types are not handled by the library itself.       */
-  /*                                                                       */
-  typedef enum  FT_Palette_Mode_
-  {
-    ft_palette_mode_rgb = 0,
-    ft_palette_mode_rgba,
-
-    ft_palette_mode_max   /* do not remove */
-
-  } FT_Palette_Mode;
-
-  /* */
-
-#endif
-
 
   /*************************************************************************/
   /*                                                                       */
@@ -311,20 +258,15 @@
   /*                    field is intended for paletted pixel modes.  Not   */
   /*                    used currently.                                    */
   /*                                                                       */
-  /* <Note>                                                                */
-  /*   For now, the only pixel modes supported by FreeType are mono and    */
-  /*   grays.  However, drivers might be added in the future to support    */
-  /*   more `colorful' options.                                            */
-  /*                                                                       */
   typedef struct  FT_Bitmap_
   {
-    int             rows;
-    int             width;
+    unsigned int    rows;
+    unsigned int    width;
     int             pitch;
     unsigned char*  buffer;
-    short           num_grays;
-    char            pixel_mode;
-    char            palette_mode;
+    unsigned short  num_grays;
+    unsigned char   pixel_mode;
+    unsigned char   palette_mode;
     void*           palette;
 
   } FT_Bitmap;
@@ -381,7 +323,7 @@
   /*                                                                       */
   /*    flags      :: A set of bit flags used to characterize the outline  */
   /*                  and give hints to the scan-converter and hinter on   */
-  /*                  how to convert/grid-fit it.  See @FT_OUTLINE_FLAGS.  */
+  /*                  how to convert/grid-fit it.  See @FT_OUTLINE_XXX.    */
   /*                                                                       */
   /* <Note>                                                                */
   /*    The B/W rasterizer only checks bit~2 in the `tags' array for the   */
@@ -402,6 +344,8 @@
 
   } FT_Outline;
 
+  /* */
+
   /* Following limits must be consistent with */
   /* FT_Outline.{n_contours,n_points}         */
 #define FT_OUTLINE_CONTOURS_MAX  SHRT_MAX
@@ -411,7 +355,7 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Enum>                                                                */
-  /*    FT_OUTLINE_FLAGS                                                   */
+  /*    FT_OUTLINE_XXX                                                     */
   /*                                                                       */
   /* <Description>                                                         */
   /*    A list of bit-field constants use for the flags in an outline's    */
@@ -492,24 +436,8 @@
 #define FT_OUTLINE_SINGLE_PASS      0x200
 
 
- /*************************************************************************
-  *
-  * @enum:
-  *   ft_outline_flags
-  *
-  * @description:
-  *   These constants are deprecated.  Please use the corresponding
-  *   @FT_OUTLINE_FLAGS values.
-  *
-  * @values:
-  *   ft_outline_none            :: See @FT_OUTLINE_NONE.
-  *   ft_outline_owner           :: See @FT_OUTLINE_OWNER.
-  *   ft_outline_even_odd_fill   :: See @FT_OUTLINE_EVEN_ODD_FILL.
-  *   ft_outline_reverse_fill    :: See @FT_OUTLINE_REVERSE_FILL.
-  *   ft_outline_ignore_dropouts :: See @FT_OUTLINE_IGNORE_DROPOUTS.
-  *   ft_outline_high_precision  :: See @FT_OUTLINE_HIGH_PRECISION.
-  *   ft_outline_single_pass     :: See @FT_OUTLINE_SINGLE_PASS.
-  */
+  /* these constants are deprecated; use the corresponding */
+  /* `FT_OUTLINE_XXX' values instead                       */
 #define ft_outline_none             FT_OUTLINE_NONE
 #define ft_outline_owner            FT_OUTLINE_OWNER
 #define ft_outline_even_odd_fill    FT_OUTLINE_EVEN_ODD_FILL
@@ -796,22 +724,8 @@
   } FT_Glyph_Format;
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Enum>                                                                */
-  /*    ft_glyph_format_xxx                                                */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A list of deprecated constants.  Use the corresponding             */
-  /*    @FT_Glyph_Format values instead.                                   */
-  /*                                                                       */
-  /* <Values>                                                              */
-  /*    ft_glyph_format_none      :: See @FT_GLYPH_FORMAT_NONE.            */
-  /*    ft_glyph_format_composite :: See @FT_GLYPH_FORMAT_COMPOSITE.       */
-  /*    ft_glyph_format_bitmap    :: See @FT_GLYPH_FORMAT_BITMAP.          */
-  /*    ft_glyph_format_outline   :: See @FT_GLYPH_FORMAT_OUTLINE.         */
-  /*    ft_glyph_format_plotter   :: See @FT_GLYPH_FORMAT_PLOTTER.         */
-  /*                                                                       */
+  /* these constants are deprecated; use the corresponding */
+  /* `FT_Glyph_Format' values instead.                     */
 #define ft_glyph_format_none       FT_GLYPH_FORMAT_NONE
 #define ft_glyph_format_composite  FT_GLYPH_FORMAT_COMPOSITE
 #define ft_glyph_format_bitmap     FT_GLYPH_FORMAT_BITMAP
@@ -856,6 +770,21 @@
   /* <Description>                                                         */
   /*    This section contains technical definitions.                       */
   /*                                                                       */
+  /* <Order>                                                               */
+  /*    FT_Raster                                                          */
+  /*    FT_Span                                                            */
+  /*    FT_SpanFunc                                                        */
+  /*                                                                       */
+  /*    FT_Raster_Params                                                   */
+  /*    FT_RASTER_FLAG_XXX                                                 */
+  /*                                                                       */
+  /*    FT_Raster_NewFunc                                                  */
+  /*    FT_Raster_DoneFunc                                                 */
+  /*    FT_Raster_ResetFunc                                                */
+  /*    FT_Raster_SetModeFunc                                              */
+  /*    FT_Raster_RenderFunc                                               */
+  /*    FT_Raster_Funcs                                                    */
+  /*                                                                       */
   /*************************************************************************/
 
 
@@ -865,8 +794,8 @@
   /*    FT_Raster                                                          */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A handle (pointer) to a raster object.  Each object can be used    */
-  /*    independently to convert an outline into a bitmap or pixmap.       */
+  /*    An opaque handle (pointer) to a raster object.  Each object can be */
+  /*    used independently to convert an outline into a bitmap or pixmap.  */
   /*                                                                       */
   typedef struct FT_RasterRec_*  FT_Raster;
 
@@ -877,8 +806,8 @@
   /*    FT_Span                                                            */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure used to model a single span of gray (or black) pixels  */
-  /*    when rendering a monochrome or anti-aliased bitmap.                */
+  /*    A structure used to model a single span of gray pixels when        */
+  /*    rendering an anti-aliased bitmap.                                  */
   /*                                                                       */
   /* <Fields>                                                              */
   /*    x        :: The span's horizontal start position.                  */
@@ -886,8 +815,7 @@
   /*    len      :: The span's length in pixels.                           */
   /*                                                                       */
   /*    coverage :: The span color/coverage, ranging from 0 (background)   */
-  /*                to 255 (foreground).  Only used for anti-aliased       */
-  /*                rendering.                                             */
+  /*                to 255 (foreground).                                   */
   /*                                                                       */
   /* <Note>                                                                */
   /*    This structure is used by the span drawing callback type named     */
@@ -957,22 +885,7 @@
   /*    FT_Raster_BitTest_Func                                             */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    THIS TYPE IS DEPRECATED.  DO NOT USE IT.                           */
-  /*                                                                       */
-  /*    A function used as a call-back by the monochrome scan-converter    */
-  /*    to test whether a given target pixel is already set to the drawing */
-  /*    `color'.  These tests are crucial to implement drop-out control    */
-  /*    per-se the TrueType spec.                                          */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    y     :: The pixel's y~coordinate.                                 */
-  /*                                                                       */
-  /*    x     :: The pixel's x~coordinate.                                 */
-  /*                                                                       */
-  /*    user  :: User-supplied data that is passed to the callback.        */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*   1~if the pixel is `set', 0~otherwise.                               */
+  /*    Deprecated, unimplemented.                                         */
   /*                                                                       */
   typedef int
   (*FT_Raster_BitTest_Func)( int    y,
@@ -986,21 +899,7 @@
   /*    FT_Raster_BitSet_Func                                              */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    THIS TYPE IS DEPRECATED.  DO NOT USE IT.                           */
-  /*                                                                       */
-  /*    A function used as a call-back by the monochrome scan-converter    */
-  /*    to set an individual target pixel.  This is crucial to implement   */
-  /*    drop-out control according to the TrueType specification.          */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    y     :: The pixel's y~coordinate.                                 */
-  /*                                                                       */
-  /*    x     :: The pixel's x~coordinate.                                 */
-  /*                                                                       */
-  /*    user  :: User-supplied data that is passed to the callback.        */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    1~if the pixel is `set', 0~otherwise.                              */
+  /*    Deprecated, unimplemented.                                         */
   /*                                                                       */
   typedef void
   (*FT_Raster_BitSet_Func)( int    y,
@@ -1034,8 +933,8 @@
   /*                              pixmap's buffer _must_ be zeroed before  */
   /*                              rendering.                               */
   /*                                                                       */
-  /*                              Note that for now, direct rendering is   */
-  /*                              only possible with anti-aliased glyphs.  */
+  /*                              Direct rendering is only possible with   */
+  /*                              anti-aliased glyphs.                     */
   /*                                                                       */
   /*    FT_RASTER_FLAG_CLIP    :: This flag is only used in direct         */
   /*                              rendering mode.  If set, the output will */
@@ -1053,7 +952,8 @@
 #define FT_RASTER_FLAG_DIRECT   0x2
 #define FT_RASTER_FLAG_CLIP     0x4
 
-  /* deprecated */
+  /* these constants are deprecated; use the corresponding */
+  /* `FT_RASTER_FLAG_XXX' values instead                   */
 #define ft_raster_flag_default  FT_RASTER_FLAG_DEFAULT
 #define ft_raster_flag_aa       FT_RASTER_FLAG_AA
 #define ft_raster_flag_direct   FT_RASTER_FLAG_DIRECT
@@ -1079,11 +979,11 @@
   /*                                                                       */
   /*    gray_spans  :: The gray span drawing callback.                     */
   /*                                                                       */
-  /*    black_spans :: The black span drawing callback.  UNIMPLEMENTED!    */
+  /*    black_spans :: Unused.                                             */
   /*                                                                       */
-  /*    bit_test    :: The bit test callback.  UNIMPLEMENTED!              */
+  /*    bit_test    :: Unused.                                             */
   /*                                                                       */
-  /*    bit_set     :: The bit set callback.  UNIMPLEMENTED!               */
+  /*    bit_set     :: Unused.                                             */
   /*                                                                       */
   /*    user        :: User-supplied data that is passed to each drawing   */
   /*                   callback.                                           */
@@ -1100,15 +1000,9 @@
   /*                                                                       */
   /*    If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the      */
   /*    raster will call the `gray_spans' callback to draw gray pixel      */
-  /*    spans, in the case of an aa glyph bitmap, it will call             */
-  /*    `black_spans', and `bit_test' and `bit_set' in the case of a       */
-  /*    monochrome bitmap.  This allows direct composition over a          */
-  /*    pre-existing bitmap through user-provided callbacks to perform the */
-  /*    span drawing/composition.                                          */
-  /*                                                                       */
-  /*    Note that the `bit_test' and `bit_set' callbacks are required when */
-  /*    rendering a monochrome bitmap, as they are crucial to implement    */
-  /*    correct drop-out control as defined in the TrueType specification. */
+  /*    spans.  This allows direct composition over a pre-existing bitmap  */
+  /*    through user-provided callbacks to perform the span drawing and    */
+  /*    composition.    Not supported by the monochrome rasterizer.        */
   /*                                                                       */
   typedef struct  FT_Raster_Params_
   {
@@ -1116,9 +1010,9 @@
     const void*             source;
     int                     flags;
     FT_SpanFunc             gray_spans;
-    FT_SpanFunc             black_spans;  /* doesn't work! */
-    FT_Raster_BitTest_Func  bit_test;     /* doesn't work! */
-    FT_Raster_BitSet_Func   bit_set;      /* doesn't work! */
+    FT_SpanFunc             black_spans;  /* unused */
+    FT_Raster_BitTest_Func  bit_test;     /* unused */
+    FT_Raster_BitSet_Func   bit_set;      /* unused */
     void*                   user;
     FT_BBox                 clip_box;
 
@@ -1179,10 +1073,10 @@
   /*    FT_Raster_ResetFunc                                                */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    FreeType provides an area of memory called the `render pool',      */
-  /*    available to all registered rasters.  This pool can be freely used */
-  /*    during a given scan-conversion but is shared by all rasters.  Its  */
-  /*    content is thus transient.                                         */
+  /*    FreeType used to provide an area of memory called the `render      */
+  /*    pool' available to all registered rasters.  This was not thread    */
+  /*    safe however and now FreeType never allocates this pool.  NULL     */
+  /*    is always passed in as pool_base.                                  */
   /*                                                                       */
   /*    This function is called each time the render pool changes, or just */
   /*    after a new raster object is created.                              */
@@ -1195,10 +1089,9 @@
   /*    pool_size :: The size in bytes of the render pool.                 */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    Rasters can ignore the render pool and rely on dynamic memory      */
+  /*    Rasters should ignore the render pool and rely on dynamic or stack */
   /*    allocation if they want to (a handle to the memory allocator is    */
-  /*    passed to the raster constructor).  However, this is not           */
-  /*    recommended for efficiency purposes.                               */
+  /*    passed to the raster constructor).                                 */
   /*                                                                       */
   typedef void
   (*FT_Raster_ResetFunc)( FT_Raster       raster,
@@ -1305,7 +1198,6 @@
 
   } FT_Raster_Funcs;
 
-
   /* */
 
 
diff --git a/include/ftincrem.h b/include/ftincrem.h
index aaf689f..840af25 100644
--- a/include/ftincrem.h
+++ b/include/ftincrem.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType incremental loading (specification).                        */
 /*                                                                         */
-/*  Copyright 2002, 2003, 2006, 2007, 2008, 2010 by                        */
+/*  Copyright 2002-2015 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 @@
    * @description:
    *   This section contains various functions used to perform so-called
    *   `incremental' glyph loading.  This is a mode where all glyphs loaded
-   *   from a given @FT_Face are provided by the client application,
+   *   from a given @FT_Face are provided by the client application.
    *
    *   Apart from that, all other tables are loaded normally from the font
    *   file.  This mode is useful when FreeType is used within another
@@ -345,6 +345,7 @@
 
   /* */
 
+
 FT_END_HEADER
 
 #endif /* __FTINCREM_H__ */
diff --git a/include/ftlcdfil.h b/include/ftlcdfil.h
index 39206f0..4cd999a 100644
--- a/include/ftlcdfil.h
+++ b/include/ftlcdfil.h
@@ -5,7 +5,7 @@
 /*    FreeType API for color filtering of subpixel bitmap glyphs           */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2006-2008, 2010, 2013 by                                     */
+/*  Copyright 2006-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -56,7 +56,7 @@
    *
    *   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
+   *   (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
    *
diff --git a/include/ftlist.h b/include/ftlist.h
index 241e21e..12b48c7 100644
--- a/include/ftlist.h
+++ b/include/ftlist.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Generic list support for FreeType (specification).                   */
 /*                                                                         */
-/*  Copyright 1996-2001, 2003, 2007, 2010, 2013 by                         */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -248,7 +248,7 @@
   /*    list    :: A handle to the list.                                   */
   /*                                                                       */
   /*    destroy :: A list destructor that will be applied to each element  */
-  /*               of the list.                                            */
+  /*               of the list.  Set this to NULL if not needed.           */
   /*                                                                       */
   /*    memory  :: The current memory object that handles deallocation.    */
   /*                                                                       */
@@ -265,7 +265,6 @@
                     FT_Memory           memory,
                     void*               user );
 
-
   /* */
 
 
diff --git a/include/ftlzw.h b/include/ftlzw.h
index 00d4016..d3ec28e 100644
--- a/include/ftlzw.h
+++ b/include/ftlzw.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    LZW-compressed stream support.                                       */
 /*                                                                         */
-/*  Copyright 2004, 2006 by                                                */
+/*  Copyright 2004-2015 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_Stream_OpenLZW( FT_Stream  stream,
                      FT_Stream  source );
 
- /* */
+  /* */
 
 
 FT_END_HEADER
diff --git a/include/ftmac.h b/include/ftmac.h
index 42874fe..14c55cf 100644
--- a/include/ftmac.h
+++ b/include/ftmac.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Additional Mac-specific API.                                         */
 /*                                                                         */
-/*  Copyright 1996-2001, 2004, 2006, 2007, 2013 by                         */
+/*  Copyright 1996-2015 by                                                 */
 /*  Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.     */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/ftmm.h b/include/ftmm.h
index 837975a..6ef4798 100644
--- a/include/ftmm.h
+++ b/include/ftmm.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType Multiple Master font interface (specification).             */
 /*                                                                         */
-/*  Copyright 1996-2001, 2003, 2004, 2006, 2009, 2013 by                   */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -95,8 +95,8 @@
   /*                                                                       */
   /*    num_designs :: Number of designs; should be normally 2^num_axis    */
   /*                   even though the Type~1 specification strangely      */
-  /*                   allows for intermediate designs to be present. This */
-  /*                   number cannot exceed~16.                            */
+  /*                   allows for intermediate designs to be present.      */
+  /*                   This number cannot exceed~16.                       */
   /*                                                                       */
   /*    axis        :: A table of axis descriptors.                        */
   /*                                                                       */
@@ -201,10 +201,10 @@
   /*                       associated with them.  The font can tell the    */
   /*                       user that, for example, Weight=1.5 is `Bold'.   */
   /*                                                                       */
-  /*    axis            :: A table of axis descriptors.                    */
+  /*    axis            :: An axis descriptor table.                       */
   /*                       GX fonts contain slightly more data than MM.    */
   /*                                                                       */
-  /*    namedstyles     :: A table of named styles.                        */
+  /*    namedstyle      :: A named style table.                            */
   /*                       Only meaningful with GX.                        */
   /*                                                                       */
   typedef struct  FT_MM_Var_
@@ -218,9 +218,6 @@
   } FT_MM_Var;
 
 
-  /* */
-
-
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -283,8 +280,10 @@
   /*    face       :: A handle to the source face.                         */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    num_coords :: The number of design coordinates (must be equal to   */
-  /*                  the number of axes in the font).                     */
+  /*    num_coords :: The number of available design coordinates.  If it   */
+  /*                  is larger than the number of axes, ignore the excess */
+  /*                  values.  If it is smaller than the number of axes,   */
+  /*                  use default values for the remaining axes.           */
   /*                                                                       */
   /*    coords     :: An array of design coordinates.                      */
   /*                                                                       */
@@ -310,8 +309,10 @@
   /*    face       :: A handle to the source face.                         */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    num_coords :: The number of design coordinates (must be equal to   */
-  /*                  the number of axes in the font).                     */
+  /*    num_coords :: The number of available design coordinates.  If it   */
+  /*                  is larger than the number of axes, ignore the excess */
+  /*                  values.  If it is smaller than the number of axes,   */
+  /*                  use default values for the remaining axes.           */
   /*                                                                       */
   /*    coords     :: An array of design coordinates.                      */
   /*                                                                       */
@@ -337,8 +338,10 @@
   /*    face       :: A handle to the source face.                         */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    num_coords :: The number of design coordinates (must be equal to   */
-  /*                  the number of axes in the font).                     */
+  /*    num_coords :: The number of available design coordinates.  If it   */
+  /*                  is larger than the number of axes, ignore the excess */
+  /*                  values.  If it is smaller than the number of axes,   */
+  /*                  use default values for the remaining axes.           */
   /*                                                                       */
   /*    coords     :: The design coordinates array (each element must be   */
   /*                  between 0 and 1.0).                                  */
@@ -365,7 +368,6 @@
                                 FT_UInt    num_coords,
                                 FT_Fixed*  coords );
 
-
   /* */
 
 
diff --git a/include/ftmodapi.h b/include/ftmodapi.h
index 22878f8..2ef3f46 100644
--- a/include/ftmodapi.h
+++ b/include/ftmodapi.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType modules public interface (specification).                   */
 /*                                                                         */
-/*  Copyright 1996-2003, 2006, 2008-2010, 2012, 2013 by                    */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -75,6 +75,33 @@
   /*                                                                       */
   /*    Note that the FreeType Cache sub-system is not a FreeType module.  */
   /*                                                                       */
+  /* <Order>                                                               */
+  /*    FT_Module                                                          */
+  /*    FT_Module_Constructor                                              */
+  /*    FT_Module_Destructor                                               */
+  /*    FT_Module_Requester                                                */
+  /*    FT_Module_Class                                                    */
+  /*                                                                       */
+  /*    FT_Add_Module                                                      */
+  /*    FT_Get_Module                                                      */
+  /*    FT_Remove_Module                                                   */
+  /*    FT_Add_Default_Modules                                             */
+  /*                                                                       */
+  /*    FT_Property_Set                                                    */
+  /*    FT_Property_Get                                                    */
+  /*                                                                       */
+  /*    FT_New_Library                                                     */
+  /*    FT_Done_Library                                                    */
+  /*    FT_Reference_Library                                               */
+  /*                                                                       */
+  /*    FT_Renderer                                                        */
+  /*    FT_Renderer_Class                                                  */
+  /*                                                                       */
+  /*    FT_Get_Renderer                                                    */
+  /*    FT_Set_Renderer                                                    */
+  /*                                                                       */
+  /*    FT_Set_Debug_Hook                                                  */
+  /*                                                                       */
   /*************************************************************************/
 
 
@@ -442,7 +469,9 @@
   /* <Description>                                                         */
   /*    This function is used to create a new FreeType library instance    */
   /*    from a given memory object.  It is thus possible to use libraries  */
-  /*    with distinct memory allocators within the same program.           */
+  /*    with distinct memory allocators within the same program.  Note,    */
+  /*    however, that the used @FT_Memory structure is expected to remain  */
+  /*    valid for the life of the @FT_Library object.                      */
   /*                                                                       */
   /*    Normally, you would call this function (followed by a call to      */
   /*    @FT_Add_Default_Modules or a series of calls to @FT_Add_Module)    */
@@ -491,7 +520,7 @@
   FT_EXPORT( FT_Error )
   FT_Done_Library( FT_Library  library );
 
-/* */
+  /* */
 
   typedef void
   (*FT_DebugHook_Func)( void*  arg );
@@ -629,7 +658,6 @@
   FT_EXPORT( FT_TrueTypeEngineType )
   FT_Get_TrueType_Engine_Type( FT_Library  library );
 
-
   /* */
 
 
diff --git a/include/ftmoderr.h b/include/ftmoderr.h
index 5a27db1..9d7f981 100644
--- a/include/ftmoderr.h
+++ b/include/ftmoderr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType module error offsets (specification).                       */
 /*                                                                         */
-/*  Copyright 2001-2005, 2010, 2013 by                                     */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/ftotval.h b/include/ftotval.h
index bb52dc4..e744b71 100644
--- a/include/ftotval.h
+++ b/include/ftotval.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for validating OpenType tables (specification).         */
 /*                                                                         */
-/*  Copyright 2004-2007, 2013 by                                           */
+/*  Copyright 2004-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -58,6 +58,12 @@
   /*    This section contains the declaration of functions to validate     */
   /*    some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH).         */
   /*                                                                       */
+  /* <Order>                                                               */
+  /*    FT_OpenType_Validate                                               */
+  /*    FT_OpenType_Free                                                   */
+  /*                                                                       */
+  /*    FT_VALIDATE_OTXXX                                                  */
+  /*                                                                       */
   /*************************************************************************/
 
 
@@ -107,8 +113,6 @@
                         FT_VALIDATE_JSTF | \
                         FT_VALIDATE_MATH
 
-  /* */
-
  /**********************************************************************
   *
   * @function:
@@ -165,8 +169,6 @@
                         FT_Bytes  *GSUB_table,
                         FT_Bytes  *JSTF_table );
 
-  /* */
-
  /**********************************************************************
   *
   * @function:
@@ -191,8 +193,7 @@
   FT_OpenType_Free( FT_Face   face,
                     FT_Bytes  table );
 
-
- /* */
+  /* */
 
 
 FT_END_HEADER
diff --git a/include/ftoutln.h b/include/ftoutln.h
index 6c6d3f9..106cfde 100644
--- a/include/ftoutln.h
+++ b/include/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-2003, 2005-2014 by                                      */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -52,7 +52,6 @@
   /*                                                                       */
   /* <Order>                                                               */
   /*    FT_Outline                                                         */
-  /*    FT_OUTLINE_FLAGS                                                   */
   /*    FT_Outline_New                                                     */
   /*    FT_Outline_Done                                                    */
   /*    FT_Outline_Copy                                                    */
@@ -68,13 +67,17 @@
   /*                                                                       */
   /*    FT_Outline_Get_Bitmap                                              */
   /*    FT_Outline_Render                                                  */
-  /*                                                                       */
   /*    FT_Outline_Decompose                                               */
   /*    FT_Outline_Funcs                                                   */
-  /*    FT_Outline_MoveTo_Func                                             */
-  /*    FT_Outline_LineTo_Func                                             */
-  /*    FT_Outline_ConicTo_Func                                            */
-  /*    FT_Outline_CubicTo_Func                                            */
+  /*    FT_Outline_MoveToFunc                                              */
+  /*    FT_Outline_LineToFunc                                              */
+  /*    FT_Outline_ConicToFunc                                             */
+  /*    FT_Outline_CubicToFunc                                             */
+  /*                                                                       */
+  /*    FT_Orientation                                                     */
+  /*    FT_Outline_Get_Orientation                                         */
+  /*                                                                       */
+  /*    FT_OUTLINE_XXX                                                     */
   /*                                                                       */
   /*************************************************************************/
 
@@ -535,7 +538,7 @@
   *
   * @description:
   *   This function analyzes a glyph outline and tries to compute its
-  *   fill orientation (see @FT_Orientation).  This is done by integrating 
+  *   fill orientation (see @FT_Orientation).  This is done by integrating
   *   the total area covered by the outline. The positive integral
   *   corresponds to the clockwise orientation and @FT_ORIENTATION_POSTSCRIPT
   *   is returned. The negative integral corresponds to the counter-clockwise
@@ -555,7 +558,6 @@
   FT_EXPORT( FT_Orientation )
   FT_Outline_Get_Orientation( FT_Outline*  outline );
 
-
   /* */
 
 
diff --git a/include/ftpfr.h b/include/ftpfr.h
index 0b7b7d4..a1c02a2 100644
--- a/include/ftpfr.h
+++ b/include/ftpfr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for accessing PFR-specific data (specification only).   */
 /*                                                                         */
-/*  Copyright 2002, 2003, 2004, 2006, 2008, 2009 by                        */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -161,7 +161,7 @@
                       FT_UInt   gindex,
                       FT_Pos   *aadvance );
 
- /* */
+  /* */
 
 
 FT_END_HEADER
diff --git a/include/ftrender.h b/include/ftrender.h
index dd0229b..ec8da70 100644
--- a/include/ftrender.h
+++ b/include/ftrender.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType renderer modules public interface (specification).          */
 /*                                                                         */
-/*  Copyright 1996-2001, 2005, 2006, 2010 by                               */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -212,13 +212,8 @@
   /*                                                                       */
   /*    This doesn't change the current renderer for other formats.        */
   /*                                                                       */
-  /*    Currently, only the B/W renderer, if compiled with                 */
-  /*    FT_RASTER_OPTION_ANTI_ALIASING (providing a 5-levels               */
-  /*    anti-aliasing mode; this option must be set directly in            */
-  /*    `ftraster.c' and is undefined by default) accepts a single tag     */
-  /*    `pal5' to set its gray palette as a character string with          */
-  /*    5~elements.  Consequently, the third and fourth argument are zero  */
-  /*    normally.                                                          */
+  /*    Currently, no FreeType renderer module uses `parameters'; you      */
+  /*    should thus always pass NULL as the value.                         */
   /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Set_Renderer( FT_Library     library,
@@ -226,7 +221,6 @@
                    FT_UInt        num_params,
                    FT_Parameter*  parameters );
 
-
   /* */
 
 
diff --git a/include/ftsizes.h b/include/ftsizes.h
index 4167045..bef8424 100644
--- a/include/ftsizes.h
+++ b/include/ftsizes.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType size objects management (specification).                    */
 /*                                                                         */
-/*  Copyright 1996-2001, 2003, 2004, 2006, 2009, 2013 by                   */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/ftsnames.h b/include/ftsnames.h
index 88af440..0f7fbe1 100644
--- a/include/ftsnames.h
+++ b/include/ftsnames.h
@@ -7,7 +7,7 @@
 /*                                                                         */
 /*    This is _not_ used to retrieve glyph names!                          */
 /*                                                                         */
-/*  Copyright 1996-2003, 2006, 2009, 2010, 2013 by                         */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/ftstroke.h b/include/ftstroke.h
index a498e4a..7ebb1e7 100644
--- a/include/ftstroke.h
+++ b/include/ftstroke.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType path stroker (specification).                               */
 /*                                                                         */
-/*  Copyright 2002-2006, 2008, 2009, 2011-2012 by                          */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -46,6 +46,38 @@
   *    This can be useful to generate `bordered' glyph, i.e., glyphs
   *    displayed with a coloured (and anti-aliased) border around their
   *    shape.
+  *
+  * @order:
+  *    FT_Stroker
+  *
+  *    FT_Stroker_LineJoin
+  *    FT_Stroker_LineCap
+  *    FT_StrokerBorder
+  *
+  *    FT_Outline_GetInsideBorder
+  *    FT_Outline_GetOutsideBorder
+  *
+  *    FT_Glyph_Stroke
+  *    FT_Glyph_StrokeBorder
+  *
+  *    FT_Stroker_New
+  *    FT_Stroker_Set
+  *    FT_Stroker_Rewind
+  *    FT_Stroker_ParseOutline
+  *    FT_Stroker_Done
+  *
+  *    FT_Stroker_BeginSubPath
+  *    FT_Stroker_EndSubPath
+  *
+  *    FT_Stroker_LineTo
+  *    FT_Stroker_ConicTo
+  *    FT_Stroker_CubicTo
+  *
+  *    FT_Stroker_GetBorderCounts
+  *    FT_Stroker_ExportBorder
+  *    FT_Stroker_GetCounts
+  *    FT_Stroker_Export
+  *
   */
 
 
@@ -55,7 +87,7 @@
   *   FT_Stroker
   *
   * @description:
-  *   Opaque handler to a path stroker object.
+  *   Opaque handle to a path stroker object.
   */
   typedef struct FT_StrokerRec_*  FT_Stroker;
 
@@ -276,6 +308,8 @@
    * @note:
    *   The radius is expressed in the same units as the outline
    *   coordinates.
+   *
+   *   This function calls @FT_Stroker_Rewind automatically.
    */
   FT_EXPORT( void )
   FT_Stroker_Set( FT_Stroker           stroker,
@@ -570,10 +604,10 @@
    *   receive all new data.
    *
    *   When an outline, or a sub-path, is `closed', the stroker generates
-   *   two independent `border' outlines, named `left' and `right'
+   *   two independent `border' outlines, named `left' and `right'.
    *
    *   When the outline, or a sub-path, is `opened', the stroker merges
-   *   the `border' outlines with caps. The `left' border receives all
+   *   the `border' outlines with caps.  The `left' border receives all
    *   points, while the `right' border becomes empty.
    *
    *   Use the function @FT_Stroker_Export instead if you want to
@@ -736,7 +770,7 @@
                          FT_Bool      inside,
                          FT_Bool      destroy );
 
- /* */
+  /* */
 
 FT_END_HEADER
 
diff --git a/include/ftsynth.h b/include/ftsynth.h
index 839ab5e..fbcbad8 100644
--- a/include/ftsynth.h
+++ b/include/ftsynth.h
@@ -5,7 +5,7 @@
 /*    FreeType synthesizing code for emboldening and slanting              */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2000-2001, 2003, 2006, 2008, 2012, 2013 by                   */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -62,8 +62,10 @@
   /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden.           */
   /*                                                                       */
   /* For emboldened outlines the height, width, and advance metrics are    */
-  /* increased by the strength of the emboldening.  You can also call      */
-  /* @FT_Outline_Get_CBox to get precise values.                           */
+  /* increased by the strength of the emboldening -- this even affects     */
+  /* mono-width fonts!                                                     */
+  /*                                                                       */
+  /* You can also call @FT_Outline_Get_CBox to get precise values.         */
   FT_EXPORT( void )
   FT_GlyphSlot_Embolden( FT_GlyphSlot  slot );
 
@@ -73,6 +75,7 @@
 
   /* */
 
+
 FT_END_HEADER
 
 #endif /* __FTSYNTH_H__ */
diff --git a/include/ftsystem.h b/include/ftsystem.h
index e07460c..2bc9999 100644
--- a/include/ftsystem.h
+++ b/include/ftsystem.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType low-level system interface definition (specification).      */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2005, 2010 by                               */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -192,6 +192,10 @@
    * @description:
    *   A handle to an input stream.
    *
+   * @also:
+   *   See @FT_StreamRec for the publicly accessible fields of a given
+   *   stream object.
+   *
    */
   typedef struct FT_StreamRec_*  FT_Stream;
 
@@ -285,6 +289,11 @@
    *   size ::
    *     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. 
+   *     (Note that this size value can occur for normal streams also; it is
+   *     thus just a hint.)
+   *
    *   pos ::
    *     The current position within the stream.
    *
@@ -335,7 +344,6 @@
 
   } FT_StreamRec;
 
-
   /* */
 
 
diff --git a/include/fttrigon.h b/include/fttrigon.h
index 65143cb..3d821ba 100644
--- a/include/fttrigon.h
+++ b/include/fttrigon.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType trigonometric functions (specification).                    */
 /*                                                                         */
-/*  Copyright 2001, 2003, 2005, 2007, 2013 by                              */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -237,7 +237,7 @@
    *
    * @input:
    *   angle ::
-   *     The address of angle.
+   *     The input angle.
    *
    */
   FT_EXPORT( void )
@@ -259,7 +259,7 @@
    *
    * @input:
    *   angle ::
-   *     The address of angle.
+   *     The input angle.
    *
    */
   FT_EXPORT( void )
diff --git a/include/ftttdrv.h b/include/ftttdrv.h
index 70ad3d5..f56040b 100644
--- a/include/ftttdrv.h
+++ b/include/ftttdrv.h
@@ -5,7 +5,7 @@
 /*    FreeType API for controlling the TrueType driver                     */
 /*    (specification only).                                                */
 /*                                                                         */
-/*  Copyright 2013 by                                                      */
+/*  Copyright 2013-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -67,13 +67,13 @@
    *   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.  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.
+   *   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.
    *
    *   Details on subpixel hinting and some of the necessary tweaks can be
    *   found in Greg Hitchcock's whitepaper at
@@ -135,32 +135,95 @@
    *   `FT_Err_Unimplemented_Feature' error.
    *
    *   Depending on the graphics framework, Microsoft uses different
-   *   bytecode engines.  As a consequence, the version numbers returned by
-   *   a call to the `GETINFO[1]' bytecode instruction are more convoluted
-   *   than desired.
+   *   bytecode and rendering engines.  As a consequence, the version
+   *   numbers returned by a call to the `GETINFO' bytecode instruction are
+   *   more convoluted than desired.
+   *
+   *   Here are two tables that try to shed some light on the possible
+   *   values for the MS rasterizer engine, together with the additional
+   *   features introduced by it.
    *
    *   {
-   *      framework   Windows version   result of GETINFO[1]
-   *     ----------------------------------------------------
-   *       GDI         before XP         35
-   *       GDI         XP and later      37
-   *       GDI+ old    before Vista      37
-   *       GDI+ old    Vista, 7          38
-   *       GDI+        after 7           40
-   *       DWrite      before 8          39
-   *       DWrite      8 and later       40
+   *     GETINFO framework               version feature
+   *     -------------------------------------------------------------------
+   *         3   GDI (Win 3.1),            v1.0  16-bit, first version
+   *             TrueImage
+   *        33   GDI (Win NT 3.1),         v1.5  32-bit
+   *             HP Laserjet
+   *        34   GDI (Win 95)              v1.6  font smoothing,
+   *                                             new SCANTYPE opcode
+   *        35   GDI (Win 98/2000)         v1.7  (UN)SCALED_COMPONENT_OFFSET
+   *                                               bits in composite glyphs
+   *        36   MGDI (Win CE 2)           v1.6+ classic ClearType
+   *        37   GDI (XP and later),       v1.8  ClearType
+   *             GDI+ old (before Vista)
+   *        38   GDI+ old (Vista, Win 7),  v1.9  subpixel ClearType,
+   *             WPF                             Y-direction ClearType,
+   *                                             additional error checking
+   *        39   DWrite (before Win 8)     v2.0  subpixel ClearType flags
+   *                                               in GETINFO opcode,
+   *                                             bug fixes
+   *        40   GDI+ (after Win 7),       v2.1  Y-direction ClearType flag
+   *             DWrite (Win 8)                    in GETINFO opcode,
+   *                                             Gray ClearType
    *   }
    *
-   *   Since FreeType doesn't provide all capabilities of DWrite ClearType,
-   *   using version~38 seems justified.
+   *   The `version' field gives a rough orientation only, since some
+   *   applications provided certain features much earlier (as an example,
+   *   Microsoft Reader used subpixel and Y-direction ClearType already in
+   *   Windows 2000).  Similarly, updates to a given framework might include
+   *   improved hinting support.
+   *
+   *   {
+   *      version   sampling          rendering        comment
+   *               x        y       x           y
+   *     --------------------------------------------------------------
+   *       v1.0   normal  normal  B/W           B/W    bi-level
+   *       v1.6   high    high    gray          gray   grayscale
+   *       v1.8   high    normal  color-filter  B/W    (GDI) ClearType
+   *       v1.9   high    high    color-filter  gray   Color ClearType
+   *       v2.1   high    normal  gray          B/W    Gray ClearType
+   *       v2.1   high    high    gray          gray   Gray ClearType
+   *   }
+   *
+   *   Color and Gray ClearType are the two available variants of
+   *   `Y-direction ClearType', meaning grayscale rasterization along the
+   *   Y-direction; the name used in the TrueType specification for this
+   *   feature is `symmetric smoothing'.  `Classic ClearType' is the
+   *   original algorithm used before introducing a modified version in
+   *   Win~XP.  Another name for v1.6's grayscale rendering is `font
+   *   smoothing', and `Color ClearType' is sometimes also called `DWrite
+   *   ClearType'.  To differentiate between today's Color ClearType and the
+   *   earlier ClearType variant with B/W rendering along the vertical axis,
+   *   the latter is sometimes called `GDI ClearType'.
+   *
+   *   `Normal' and `high' sampling describe the (virtual) resolution to
+   *   access the rasterized outline after the hinting process.  `Normal'
+   *   means 1 sample per grid line (i.e., B/W).  In the current Microsoft
+   *   implementation, `high' means an extra virtual resolution of 16x16 (or
+   *   16x1) grid lines per pixel for bytecode instructions like `MIRP'.
+   *   After hinting, these 16 grid lines are mapped to 6x5 (or 6x1) grid
+   *   lines for color filtering if Color ClearType is activated.
+   *
+   *   Note that `Gray ClearType' is essentially the same as v1.6's
+   *   grayscale rendering.  However, the GETINFO instruction handles it
+   *   differently: v1.6 returns bit~12 (hinting for grayscale), while v2.1
+   *   returns bits~13 (hinting for ClearType), 18 (symmetrical smoothing),
+   *   and~19 (Gray ClearType).  Also, this mode respects bits 2 and~3 for
+   *   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.
    *
    */
 #define TT_INTERPRETER_VERSION_35  35
 #define TT_INTERPRETER_VERSION_38  38
 
-
  /* */
 
+
 FT_END_HEADER
 
 
diff --git a/include/fttypes.h b/include/fttypes.h
index bd944a4..706a1be 100644
--- a/include/fttypes.h
+++ b/include/fttypes.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType simple types definitions (specification only).              */
 /*                                                                         */
-/*  Copyright 1996-2002, 2004, 2006-2009, 2012, 2013 by                    */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -57,6 +57,8 @@
   /*    FT_UInt16                                                          */
   /*    FT_Int32                                                           */
   /*    FT_UInt32                                                          */
+  /*    FT_Int64                                                           */
+  /*    FT_UInt64                                                          */
   /*    FT_Short                                                           */
   /*    FT_UShort                                                          */
   /*    FT_Long                                                            */
@@ -78,7 +80,9 @@
   /*    FT_F2Dot14                                                         */
   /*    FT_UnitVector                                                      */
   /*    FT_F26Dot6                                                         */
+  /*    FT_Data                                                            */
   /*                                                                       */
+  /*    FT_MAKE_TAG                                                        */
   /*                                                                       */
   /*    FT_Generic                                                         */
   /*    FT_Generic_Finalizer                                               */
@@ -567,9 +571,9 @@
 
   } FT_ListRec;
 
-
   /* */
 
+
 #define FT_IS_EMPTY( list )  ( (list).head == 0 )
 #define FT_BOOL( x )  ( (FT_Bool)( x ) )
 
diff --git a/include/ftwinfnt.h b/include/ftwinfnt.h
index 0b67351..caedaa1 100644
--- a/include/ftwinfnt.h
+++ b/include/ftwinfnt.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for accessing Windows fnt-specific data.                */
 /*                                                                         */
-/*  Copyright 2003, 2004, 2008 by                                          */
+/*  Copyright 2003-2015 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 @@
    *   A list of valid values for the `charset' byte in
    *   @FT_WinFNT_HeaderRec.  Exact mapping tables for the various cpXXXX
    *   encodings (except for cp1361) can be found at
-   *   ftp://ftp.unicode.org/public in the MAPPINGS/VENDORS/MICSFT/WINDOWS
+   *   ftp://ftp.unicode.org/Public in the MAPPINGS/VENDORS/MICSFT/WINDOWS
    *   subdirectory.  cp1361 is roughly a superset of
    *   MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT.
    *
@@ -95,7 +95,7 @@
    *       second default codepage that most international versions of
    *       Windows have.  It is one of the OEM codepages from
    *
-   *         http://www.microsoft.com/globaldev/reference/cphome.mspx,
+   *         https://msdn.microsoft.com/en-us/goglobal/bb964655,
    *
    *       and is used for the `DOS boxes', to support legacy applications.
    *       A German Windows version for example usually uses ANSI codepage
@@ -259,9 +259,9 @@
   FT_Get_WinFNT_Header( FT_Face               face,
                         FT_WinFNT_HeaderRec  *aheader );
 
-
   /* */
 
+
 FT_END_HEADER
 
 #endif /* __FTWINFNT_H__ */
diff --git a/include/internal/autohint.h b/include/internal/autohint.h
index 545de93..8d5a977 100644
--- a/include/internal/autohint.h
+++ b/include/internal/autohint.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level `autohint' module-specific interface (specification).     */
 /*                                                                         */
-/*  Copyright 1996-2002, 2007, 2009, 2012 by                               */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/ftcalc.h b/include/internal/ftcalc.h
index 03bd68e..75752c3 100644
--- a/include/internal/ftcalc.h
+++ b/include/internal/ftcalc.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Arithmetic computations (specification).                             */
 /*                                                                         */
-/*  Copyright 1996-2006, 2008, 2009, 2012-2013 by                          */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -27,37 +27,224 @@
 FT_BEGIN_HEADER
 
 
-#if 0
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    FT_SqrtFixed                                                       */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes the square root of a 16.16 fixed-point value.             */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    x :: The value to compute the root for.                            */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    The result of `sqrt(x)'.                                           */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    This function is not very fast.                                    */
-  /*                                                                       */
-  FT_BASE( FT_Int32 )
-  FT_SqrtFixed( FT_Int32  x );
-
-#endif /* 0 */
-
-
   /*************************************************************************/
   /*                                                                       */
   /* FT_MulDiv() and FT_MulFix() are declared in freetype.h.               */
   /*                                                                       */
   /*************************************************************************/
 
+#ifndef  FT_CONFIG_OPTION_NO_ASSEMBLER
+  /* Provide assembler fragments for performance-critical functions. */
+  /* These must be defined `static __inline__' with GCC.             */
+
+#if defined( __CC_ARM ) || defined( __ARMCC__ )  /* RVCT */
+
+#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm
+
+  /* documentation is in freetype.h */
+
+  static __inline FT_Int32
+  FT_MulFix_arm( FT_Int32  a,
+                 FT_Int32  b )
+  {
+    register FT_Int32  t, t2;
+
+
+    __asm
+    {
+      smull t2, t,  b,  a           /* (lo=t2,hi=t) = a*b */
+      mov   a,  t,  asr #31         /* a   = (hi >> 31) */
+      add   a,  a,  #0x8000         /* a  += 0x8000 */
+      adds  t2, t2, a               /* t2 += a */
+      adc   t,  t,  #0              /* t  += carry */
+      mov   a,  t2, lsr #16         /* a   = t2 >> 16 */
+      orr   a,  a,  t,  lsl #16     /* a  |= t << 16 */
+    }
+    return a;
+  }
+
+#endif /* __CC_ARM || __ARMCC__ */
+
+
+#ifdef __GNUC__
+
+#if defined( __arm__ )                                 && \
+    ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \
+    !( defined( __CC_ARM ) || defined( __ARMCC__ ) )
+
+#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm
+
+  /* documentation is in freetype.h */
+
+  static __inline__ FT_Int32
+  FT_MulFix_arm( FT_Int32  a,
+                 FT_Int32  b )
+  {
+    register FT_Int32  t, t2;
+
+
+    __asm__ __volatile__ (
+      "smull  %1, %2, %4, %3\n\t"       /* (lo=%1,hi=%2) = a*b */
+      "mov    %0, %2, asr #31\n\t"      /* %0  = (hi >> 31) */
+#if defined( __clang__ ) && defined( __thumb2__ )
+      "add.w  %0, %0, #0x8000\n\t"      /* %0 += 0x8000 */
+#else
+      "add    %0, %0, #0x8000\n\t"      /* %0 += 0x8000 */
+#endif
+      "adds   %1, %1, %0\n\t"           /* %1 += %0 */
+      "adc    %2, %2, #0\n\t"           /* %2 += carry */
+      "mov    %0, %1, lsr #16\n\t"      /* %0  = %1 >> 16 */
+      "orr    %0, %0, %2, lsl #16\n\t"  /* %0 |= %2 << 16 */
+      : "=r"(a), "=&r"(t2), "=&r"(t)
+      : "r"(a), "r"(b)
+      : "cc" );
+    return a;
+  }
+
+#endif /* __arm__                      && */
+       /* ( __thumb2__ || !__thumb__ ) && */
+       /* !( __CC_ARM || __ARMCC__ )      */
+
+
+#if defined( __i386__ )
+
+#define FT_MULFIX_ASSEMBLER  FT_MulFix_i386
+
+  /* documentation is in freetype.h */
+
+  static __inline__ FT_Int32
+  FT_MulFix_i386( FT_Int32  a,
+                  FT_Int32  b )
+  {
+    register FT_Int32  result;
+
+
+    __asm__ __volatile__ (
+      "imul  %%edx\n"
+      "movl  %%edx, %%ecx\n"
+      "sarl  $31, %%ecx\n"
+      "addl  $0x8000, %%ecx\n"
+      "addl  %%ecx, %%eax\n"
+      "adcl  $0, %%edx\n"
+      "shrl  $16, %%eax\n"
+      "shll  $16, %%edx\n"
+      "addl  %%edx, %%eax\n"
+      : "=a"(result), "=d"(b)
+      : "a"(a), "d"(b)
+      : "%ecx", "cc" );
+    return result;
+  }
+
+#endif /* i386 */
+
+#endif /* __GNUC__ */
+
+
+#ifdef _MSC_VER /* Visual C++ */
+
+#ifdef _M_IX86
+
+#define FT_MULFIX_ASSEMBLER  FT_MulFix_i386
+
+  /* documentation is in freetype.h */
+
+  static __inline FT_Int32
+  FT_MulFix_i386( FT_Int32  a,
+                  FT_Int32  b )
+  {
+    register FT_Int32  result;
+
+    __asm
+    {
+      mov eax, a
+      mov edx, b
+      imul edx
+      mov ecx, edx
+      sar ecx, 31
+      add ecx, 8000h
+      add eax, ecx
+      adc edx, 0
+      shr eax, 16
+      shl edx, 16
+      add eax, edx
+      mov result, eax
+    }
+    return result;
+  }
+
+#endif /* _M_IX86 */
+
+#endif /* _MSC_VER */
+
+
+#if defined( __GNUC__ ) && defined( __x86_64__ )
+
+#define FT_MULFIX_ASSEMBLER  FT_MulFix_x86_64
+
+  static __inline__ FT_Int32
+  FT_MulFix_x86_64( FT_Int32  a,
+                    FT_Int32  b )
+  {
+    /* Temporarily disable the warning that C90 doesn't support */
+    /* `long long'.                                             */
+#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 6 )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wlong-long"
+#endif
+
+#if 1
+    /* Technically not an assembly fragment, but GCC does a really good */
+    /* job at inlining it and generating good machine code for it.      */
+    long long  ret, tmp;
+
+
+    ret  = (long long)a * b;
+    tmp  = ret >> 63;
+    ret += 0x8000 + tmp;
+
+    return (FT_Int32)( ret >> 16 );
+#else
+
+    /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine  */
+    /* code from the lines below.  The main issue is that `wide_a' is not  */
+    /* properly initialized by sign-extending `a'.  Instead, the generated */
+    /* machine code assumes that the register that contains `a' on input   */
+    /* can be used directly as a 64-bit value, which is wrong most of the  */
+    /* time.                                                               */
+    long long  wide_a = (long long)a;
+    long long  wide_b = (long long)b;
+    long long  result;
+
+
+    __asm__ __volatile__ (
+      "imul %2, %1\n"
+      "mov %1, %0\n"
+      "sar $63, %0\n"
+      "lea 0x8000(%1, %0), %0\n"
+      "sar $16, %0\n"
+      : "=&r"(result), "=&r"(wide_a)
+      : "r"(wide_b)
+      : "cc" );
+
+    return (FT_Int32)result;
+#endif
+
+#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 6 )
+#pragma GCC diagnostic pop
+#endif
+  }
+
+#endif /* __GNUC__ && __x86_64__ */
+
+#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
+
+
+#ifdef FT_CONFIG_OPTION_INLINE_MULFIX
+#ifdef FT_MULFIX_ASSEMBLER
+#define FT_MulFix( a, b )  FT_MULFIX_ASSEMBLER( (FT_Int32)(a), (FT_Int32)(b) )
+#endif
+#endif
+
 
   /*************************************************************************/
   /*                                                                       */
@@ -124,10 +311,11 @@
                          FT_Pos  out_x,
                          FT_Pos  out_y );
 
+
   /*
    *  Return TRUE if a corner is flat or nearly flat.  This is equivalent to
-   *  saying that the angle difference between the `in' and `out' vectors is
-   *  very small.
+   *  saying that the corner point is close to its neighbors, or inside an
+   *  ellipse defined by the neighbor focal points to be more precise.
    */
   FT_BASE( FT_Int )
   ft_corner_is_flat( FT_Pos  in_x,
@@ -139,9 +327,31 @@
   /*
    *  Return the most significant bit index.
    */
+
+#ifndef  FT_CONFIG_OPTION_NO_ASSEMBLER
+#if defined( __GNUC__ )                                          && \
+    ( __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4 ) )
+
+#if FT_SIZEOF_INT == 4
+
+#define FT_MSB( x )  ( 31 - __builtin_clz( x ) )
+
+#elif FT_SIZEOF_LONG == 4
+
+#define FT_MSB( x )  ( 31 - __builtin_clzl( x ) )
+
+#endif
+
+#endif /* __GNUC__ */
+#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
+
+#ifndef FT_MSB
+
   FT_BASE( FT_Int )
   FT_MSB( FT_UInt32  z );
 
+#endif
+
 
   /*
    *  Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses
@@ -152,6 +362,31 @@
             FT_Fixed  y );
 
 
+#if 0
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_SqrtFixed                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the square root of a 16.16 fixed-point value.             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    x :: The value to compute the root for.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The result of `sqrt(x)'.                                           */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function is not very fast.                                    */
+  /*                                                                       */
+  FT_BASE( FT_Int32 )
+  FT_SqrtFixed( FT_Int32  x );
+
+#endif /* 0 */
+
+
 #define INT_TO_F26DOT6( x )    ( (FT_Long)(x) << 6  )
 #define INT_TO_F2DOT14( x )    ( (FT_Long)(x) << 14 )
 #define INT_TO_FIXED( x )      ( (FT_Long)(x) << 16 )
diff --git a/include/internal/ftdebug.h b/include/internal/ftdebug.h
index 58a3916..216c730 100644
--- a/include/internal/ftdebug.h
+++ b/include/internal/ftdebug.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Debugging and logging component (specification).                     */
 /*                                                                         */
-/*  Copyright 1996-2002, 2004, 2006-2009, 2013 by                          */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -140,7 +140,7 @@
   /*    This function may be useful if you want to control FreeType 2's    */
   /*    debug level in your application.                                   */
   /*                                                                       */
-  FT_BASE( const char * )
+  FT_BASE( const char* )
   FT_Trace_Get_Name( FT_Int  idx );
 
 
diff --git a/include/internal/ftdriver.h b/include/internal/ftdriver.h
index 940218e..16856d3 100644
--- a/include/internal/ftdriver.h
+++ b/include/internal/ftdriver.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType font driver interface (specification).                      */
 /*                                                                         */
-/*  Copyright 1996-2003, 2006, 2008, 2011-2013 by                          */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/ftgloadr.h b/include/internal/ftgloadr.h
index ce4dc6c..970dd70 100644
--- a/include/internal/ftgloadr.h
+++ b/include/internal/ftgloadr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph loader (specification).                           */
 /*                                                                         */
-/*  Copyright 2002, 2003, 2005, 2006 by                                    */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg                       */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -121,21 +121,25 @@
                               FT_UInt         n_contours );
 
 
-#define FT_GLYPHLOADER_CHECK_P( _loader, _count )                         \
-   ( (_count) == 0 || ((_loader)->base.outline.n_points    +              \
-                       (_loader)->current.outline.n_points +              \
-                       (unsigned long)(_count)) <= (_loader)->max_points )
+#define FT_GLYPHLOADER_CHECK_P( _loader, _count )       \
+  ( (_count) == 0                                    || \
+    ( (FT_UInt)(_loader)->base.outline.n_points    +    \
+      (FT_UInt)(_loader)->current.outline.n_points +    \
+      (FT_UInt)(_count) ) <= (_loader)->max_points   )
 
-#define FT_GLYPHLOADER_CHECK_C( _loader, _count )                          \
-  ( (_count) == 0 || ((_loader)->base.outline.n_contours    +              \
-                      (_loader)->current.outline.n_contours +              \
-                      (unsigned long)(_count)) <= (_loader)->max_contours )
+#define FT_GLYPHLOADER_CHECK_C( _loader, _count )         \
+  ( (_count) == 0                                      || \
+    ( (FT_UInt)(_loader)->base.outline.n_contours    +    \
+      (FT_UInt)(_loader)->current.outline.n_contours +    \
+      (FT_UInt)(_count) ) <= (_loader)->max_contours   )
 
-#define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points,_contours )      \
-  ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points )   &&                  \
-      FT_GLYPHLOADER_CHECK_C( _loader, _contours ) )                   \
-    ? 0                                                                \
-    : FT_GlyphLoader_CheckPoints( (_loader), (_points), (_contours) ) )
+#define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points, _contours ) \
+  ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points )   &&              \
+      FT_GLYPHLOADER_CHECK_C( _loader, _contours ) )               \
+    ? 0                                                            \
+    : FT_GlyphLoader_CheckPoints( (_loader),                       \
+                                  (FT_UInt)(_points),              \
+                                  (FT_UInt)(_contours) ) )
 
 
   /* check that there is enough space to add `n_subs' sub-glyphs to */
diff --git a/include/internal/ftmemory.h b/include/internal/ftmemory.h
index 3d51aee..c0c553b 100644
--- a/include/internal/ftmemory.h
+++ b/include/internal/ftmemory.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType memory management macros (specification).               */
 /*                                                                         */
-/*  Copyright 1996-2002, 2004-2007, 2010, 2013 by                          */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg                       */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -215,11 +215,14 @@
 #define FT_MEM_SET_ERROR( cond )  ( (cond), error != 0 )
 
 
-#define FT_MEM_SET( dest, byte, count )     ft_memset( dest, byte, count )
+#define FT_MEM_SET( dest, byte, count )               \
+          ft_memset( dest, byte, (FT_Offset)(count) )
 
-#define FT_MEM_COPY( dest, source, count )  ft_memcpy( dest, source, count )
+#define FT_MEM_COPY( dest, source, count )              \
+          ft_memcpy( dest, source, (FT_Offset)(count) )
 
-#define FT_MEM_MOVE( dest, source, count )  ft_memmove( dest, source, count )
+#define FT_MEM_MOVE( dest, source, count )               \
+          ft_memmove( dest, source, (FT_Offset)(count) )
 
 
 #define FT_MEM_ZERO( dest, count )  FT_MEM_SET( dest, 0, count )
@@ -227,14 +230,19 @@
 #define FT_ZERO( p )                FT_MEM_ZERO( p, sizeof ( *(p) ) )
 
 
-#define FT_ARRAY_ZERO( dest, count )                        \
-          FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) )
+#define FT_ARRAY_ZERO( dest, count )                             \
+          FT_MEM_ZERO( dest,                                     \
+                       (FT_Offset)(count) * sizeof ( *(dest) ) )
 
-#define FT_ARRAY_COPY( dest, source, count )                        \
-          FT_MEM_COPY( dest, source, (count) * sizeof ( *(dest) ) )
+#define FT_ARRAY_COPY( dest, source, count )                     \
+          FT_MEM_COPY( dest,                                     \
+                       source,                                   \
+                       (FT_Offset)(count) * sizeof ( *(dest) ) )
 
-#define FT_ARRAY_MOVE( dest, source, count )                        \
-          FT_MEM_MOVE( dest, source, (count) * sizeof ( *(dest) ) )
+#define FT_ARRAY_MOVE( dest, source, count )                     \
+          FT_MEM_MOVE( dest,                                     \
+                       source,                                   \
+                       (FT_Offset)(count) * sizeof ( *(dest) ) )
 
 
   /*
diff --git a/include/internal/ftobjs.h b/include/internal/ftobjs.h
index faa37f8..37317a4 100644
--- a/include/internal/ftobjs.h
+++ b/include/internal/ftobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType private base classes (specification).                   */
 /*                                                                         */
-/*  Copyright 1996-2006, 2008, 2010, 2012-2013 by                          */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -72,12 +72,23 @@
 
 #define FT_ABS( a )     ( (a) < 0 ? -(a) : (a) )
 
+  /*
+   *  Approximate sqrt(x*x+y*y) using the `alpha max plus beta min'
+   *  algorithm.  We use alpha = 1, beta = 3/8, giving us results with a
+   *  largest error less than 7% compared to the exact value.
+   */
+#define FT_HYPOT( x, y )                 \
+          ( x = FT_ABS( x ),             \
+            y = FT_ABS( y ),             \
+            x > y ? x + ( 3 * y >> 3 )   \
+                  : y + ( 3 * x >> 3 ) )
 
-#define FT_PAD_FLOOR( x, n )  ( (x) & ~((n)-1) )
+  /* we use the TYPEOF macro to suppress signedness compilation warnings */
+#define FT_PAD_FLOOR( x, n )  ( (x) & ~TYPEOF( x )( (n)-1 ) )
 #define FT_PAD_ROUND( x, n )  FT_PAD_FLOOR( (x) + ((n)/2), n )
 #define FT_PAD_CEIL( x, n )   FT_PAD_FLOOR( (x) + ((n)-1), n )
 
-#define FT_PIX_FLOOR( x )     ( (x) & ~63 )
+#define FT_PIX_FLOOR( x )     ( (x) & ~TYPEOF( x )63 )
 #define FT_PIX_ROUND( x )     FT_PIX_FLOOR( (x) + 32 )
 #define FT_PIX_CEIL( x )      FT_PIX_FLOOR( (x) + 63 )
 
@@ -394,7 +405,7 @@
   /*    glyph_hints       :: Format-specific glyph hints management.       */
   /*                                                                       */
 
-#define FT_GLYPH_OWN_BITMAP  0x1
+#define FT_GLYPH_OWN_BITMAP  0x1U
 
   typedef struct  FT_Slot_InternalRec_
   {
@@ -603,12 +614,12 @@
 
 #define FT_REQUEST_WIDTH( req )                                            \
           ( (req)->horiResolution                                          \
-              ? (FT_Pos)( (req)->width * (req)->horiResolution + 36 ) / 72 \
+              ? ( (req)->width * (FT_Pos)(req)->horiResolution + 36 ) / 72 \
               : (req)->width )
 
 #define FT_REQUEST_HEIGHT( req )                                            \
           ( (req)->vertResolution                                           \
-              ? (FT_Pos)( (req)->height * (req)->vertResolution + 36 ) / 72 \
+              ? ( (req)->height * (FT_Pos)(req)->vertResolution + 36 ) / 72 \
               : (req)->height )
 
 
@@ -730,9 +741,8 @@
   /*     faces_list   :: The list of faces currently opened by this        */
   /*                     driver.                                           */
   /*                                                                       */
-  /*     glyph_loader :: The glyph loader for all faces managed by this    */
-  /*                     driver.  This object isn't defined for unscalable */
-  /*                     formats.                                          */
+  /*     glyph_loader :: Unused.  Used to be glyph loader for all faces    */
+  /*                     managed by this driver.                           */
   /*                                                                       */
   typedef struct  FT_DriverRec_
   {
diff --git a/include/internal/ftpic.h b/include/internal/ftpic.h
index 485ce7a..7f9154f 100644
--- a/include/internal/ftpic.h
+++ b/include/internal/ftpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services (declaration).       */
 /*                                                                         */
-/*  Copyright 2009, 2012 by                                                */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/ftrfork.h b/include/internal/ftrfork.h
index d750cbe..da61ca7 100644
--- a/include/internal/ftrfork.h
+++ b/include/internal/ftrfork.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Embedded resource forks accessor (specification).                    */
 /*                                                                         */
-/*  Copyright 2004, 2006, 2007, 2012, 2013 by                              */
+/*  Copyright 2004-2015 by                                                 */
 /*  Masatake YAMATO and Redhat K.K.                                        */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -44,7 +44,7 @@
   typedef struct  FT_RFork_Ref_
   {
     FT_UShort  res_id;
-    FT_ULong   offset;
+    FT_Long    offset;
 
   } FT_RFork_Ref;
 
@@ -83,7 +83,7 @@
 
   /* this array is a storage in non-PIC mode, so ; is needed in END */
 #define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type )  \
-          const type name[] = {
+          static const type name[] = {
 #define CONST_FT_RFORK_RULE_ARRAY_ENTRY( func_suffix, type_suffix )  \
           { raccess_guess_ ## func_suffix,                           \
             FT_RFork_Rule_ ## type_suffix },
diff --git a/include/internal/ftserv.h b/include/internal/ftserv.h
index 1203ec8..8f837e4 100644
--- a/include/internal/ftserv.h
+++ b/include/internal/ftserv.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType services (specification only).                          */
 /*                                                                         */
-/*  Copyright 2003-2007, 2009, 2012, 2013 by                               */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -750,7 +750,7 @@
 #define FT_SERVICE_TRUETYPE_ENGINE_H    <internal/services/svtteng.h>
 #define FT_SERVICE_TT_CMAP_H            <internal/services/svttcmap.h>
 #define FT_SERVICE_WINFNT_H             <internal/services/svwinfnt.h>
-#define FT_SERVICE_XFREE86_NAME_H       <internal/services/svxf86nm.h>
+#define FT_SERVICE_FONT_FORMAT_H        <internal/services/svfntfmt.h>
 #define FT_SERVICE_TRUETYPE_GLYF_H      <internal/services/svttglyf.h>
 
  /* */
diff --git a/include/internal/ftstream.h b/include/internal/ftstream.h
index 2661858..384e5df 100644
--- a/include/internal/ftstream.h
+++ b/include/internal/ftstream.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Stream handling (specification).                                     */
 /*                                                                         */
-/*  Copyright 1996-2002, 2004-2006, 2011, 2013 by                          */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -361,7 +361,7 @@
                   FT_Long    distance );
 
   /* return current stream position */
-  FT_BASE( FT_Long )
+  FT_BASE( FT_ULong )
   FT_Stream_Pos( FT_Stream  stream );
 
   /* read bytes from a stream into a user-allocated buffer, returns an */
diff --git a/include/internal/fttrace.h b/include/internal/fttrace.h
index d5253db..9d28d21 100644
--- a/include/internal/fttrace.h
+++ b/include/internal/fttrace.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Tracing handling (specification only).                               */
 /*                                                                         */
-/*  Copyright 2002, 2004-2007, 2009, 2011-2014 by                          */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/ftvalid.h b/include/internal/ftvalid.h
index 12ad036..9cda6ee 100644
--- a/include/internal/ftvalid.h
+++ b/include/internal/ftvalid.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType validation support (specification).                         */
 /*                                                                         */
-/*  Copyright 2004, 2013 by                                                */
+/*  Copyright 2004-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -87,13 +87,13 @@
   /* validator structure */
   typedef struct  FT_ValidatorRec_
   {
+    ft_jmp_buf          jump_buffer; /* used for exception handling      */
+
     const FT_Byte*      base;        /* address of table in memory       */
     const FT_Byte*      limit;       /* `base' + sizeof(table) in memory */
     FT_ValidationLevel  level;       /* validation level                 */
     FT_Error            error;       /* error returned. 0 means success  */
 
-    ft_jmp_buf          jump_buffer; /* used for exception handling      */
-
   } FT_ValidatorRec;
 
 #if defined( _MSC_VER )
@@ -126,31 +126,29 @@
   /* Calls ft_validate_error.  Assumes that the `valid' local variable */
   /* holds a pointer to the current validator object.                  */
   /*                                                                   */
-  /* Use preprocessor prescan to pass FT_ERR_PREFIX.                   */
-  /*                                                                   */
-#define FT_INVALID( _prefix, _error )  FT_INVALID_( _prefix, _error )
-#define FT_INVALID_( _prefix, _error ) \
-          ft_validator_error( valid, _prefix ## _error )
+#define FT_INVALID( _error )  FT_INVALID_( _error )
+#define FT_INVALID_( _error ) \
+          ft_validator_error( valid, FT_THROW( _error ) )
 
   /* called when a broken table is detected */
 #define FT_INVALID_TOO_SHORT \
-          FT_INVALID( FT_ERR_PREFIX, Invalid_Table )
+          FT_INVALID( Invalid_Table )
 
   /* called when an invalid offset is detected */
 #define FT_INVALID_OFFSET \
-          FT_INVALID( FT_ERR_PREFIX, Invalid_Offset )
+          FT_INVALID( Invalid_Offset )
 
   /* called when an invalid format/value is detected */
 #define FT_INVALID_FORMAT \
-          FT_INVALID( FT_ERR_PREFIX, Invalid_Table )
+          FT_INVALID( Invalid_Table )
 
   /* called when an invalid glyph index is detected */
 #define FT_INVALID_GLYPH_ID \
-          FT_INVALID( FT_ERR_PREFIX, Invalid_Glyph_Index )
+          FT_INVALID( Invalid_Glyph_Index )
 
   /* called when an invalid field value is detected */
 #define FT_INVALID_DATA \
-          FT_INVALID( FT_ERR_PREFIX, Invalid_Table )
+          FT_INVALID( Invalid_Table )
 
 
 FT_END_HEADER
diff --git a/include/internal/internal.h b/include/internal/internal.h
index e0ddb06..1c1fd0e 100644
--- a/include/internal/internal.h
+++ b/include/internal/internal.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Internal header files (specification only).                          */
 /*                                                                         */
-/*  Copyright 1996-2004, 2013 by                                           */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/psaux.h b/include/internal/psaux.h
index e903114..1c5f784 100644
--- a/include/internal/psaux.h
+++ b/include/internal/psaux.h
@@ -5,7 +5,7 @@
 /*    Auxiliary functions and data structures related to PostScript fonts  */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 1996-2004, 2006, 2008, 2009, 2012 by                         */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -71,10 +71,10 @@
     (*done)( PS_Table  table );
 
     FT_Error
-    (*add)( PS_Table    table,
-            FT_Int      idx,
-            void*       object,
-            FT_PtrDist  length );
+    (*add)( PS_Table  table,
+            FT_Int    idx,
+            void*     object,
+            FT_UInt   length );
 
     void
     (*release)( PS_Table  table );
@@ -122,12 +122,12 @@
     FT_Byte*           block;          /* current memory block           */
     FT_Offset          cursor;         /* current cursor in memory block */
     FT_Offset          capacity;       /* current size of memory block   */
-    FT_Long            init;
+    FT_ULong           init;
 
     FT_Int             max_elems;
     FT_Int             num_elems;
     FT_Byte**          elements;       /* addresses of table elements */
-    FT_PtrDist*        lengths;        /* lengths of table elements   */
+    FT_UInt*           lengths;        /* lengths of table elements   */
 
     FT_Memory          memory;
     PS_Table_FuncsRec  funcs;
@@ -365,7 +365,7 @@
     (*to_bytes)( PS_Parser  parser,
                  FT_Byte*   bytes,
                  FT_Offset  max_bytes,
-                 FT_Long*   pnum_bytes,
+                 FT_ULong*  pnum_bytes,
                  FT_Bool    delimiters );
 
     FT_Int
@@ -675,9 +675,9 @@
     FT_Byte**            glyph_names;
 
     FT_Int               lenIV;        /* internal for sub routine calls */
-    FT_UInt              num_subrs;
+    FT_Int               num_subrs;
     FT_Byte**            subrs;
-    FT_PtrDist*          subrs_len;    /* array of subrs length (optional) */
+    FT_UInt*             subrs_len;    /* array of subrs length (optional) */
 
     FT_Matrix            font_matrix;
     FT_Vector            font_offset;
diff --git a/include/internal/pshints.h b/include/internal/pshints.h
index 3fb18dc..12aaaba 100644
--- a/include/internal/pshints.h
+++ b/include/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-2003, 2005-2007, 2009, 2012 by                          */
+/*  Copyright 2001-2015 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 @@
                           T1_Private*   private_dict,
                           PSH_Globals*  aglobals );
 
-  typedef FT_Error
+  typedef void
   (*PSH_Globals_SetScaleFunc)( PSH_Globals  globals,
                                FT_Fixed     x_scale,
                                FT_Fixed     y_scale,
@@ -465,7 +465,7 @@
   typedef void
   (*T2_Hints_StemsFunc)( T2_Hints   hints,
                          FT_UInt    dimension,
-                         FT_UInt    count,
+                         FT_Int     count,
                          FT_Fixed*  coordinates );
 
 
diff --git a/include/internal/services/svbdf.h b/include/internal/services/svbdf.h
index 0974752..865b536 100644
--- a/include/internal/services/svbdf.h
+++ b/include/internal/services/svbdf.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType BDF services (specification).                           */
 /*                                                                         */
-/*  Copyright 2003, 2009, 2012 by                                          */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/services/svcid.h b/include/internal/services/svcid.h
index 6be3f93..4a535a6 100644
--- a/include/internal/services/svcid.h
+++ b/include/internal/services/svcid.h
@@ -4,7 +4,8 @@
 /*                                                                         */
 /*    The FreeType CID font services (specification).                      */
 /*                                                                         */
-/*  Copyright 2007, 2009, 2012 by Derek Clegg, Michael Toftdal.            */
+/*  Copyright 2007-2015 by                                                 */
+/*  Derek Clegg and Michael Toftdal.                                       */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
 /*  modified, and distributed under the terms of the FreeType project      */
diff --git a/include/internal/services/svxf86nm.h b/include/internal/services/svfntfmt.h
similarity index 65%
rename from include/internal/services/svxf86nm.h
rename to include/internal/services/svfntfmt.h
index ca5d884..f8b3617 100644
--- a/include/internal/services/svxf86nm.h
+++ b/include/internal/services/svfntfmt.h
@@ -1,10 +1,10 @@
 /***************************************************************************/
 /*                                                                         */
-/*  svxf86nm.h                                                             */
+/*  svfntfmt.h                                                             */
 /*                                                                         */
-/*    The FreeType XFree86 services (specification only).                  */
+/*    The FreeType font format service (specification only).               */
 /*                                                                         */
-/*  Copyright 2003 by                                                      */
+/*  Copyright 2003-2015 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 __SVXF86NM_H__
-#define __SVXF86NM_H__
+#ifndef __SVFNTFMT_H__
+#define __SVFNTFMT_H__
 
 #include FT_INTERNAL_SERVICE_H
 
@@ -31,17 +31,17 @@
    *  is a simple constant string pointer.
    */
 
-#define FT_SERVICE_ID_XF86_NAME  "xf86-driver-name"
+#define FT_SERVICE_ID_FONT_FORMAT  "font-format"
 
-#define FT_XF86_FORMAT_TRUETYPE  "TrueType"
-#define FT_XF86_FORMAT_TYPE_1    "Type 1"
-#define FT_XF86_FORMAT_BDF       "BDF"
-#define FT_XF86_FORMAT_PCF       "PCF"
-#define FT_XF86_FORMAT_TYPE_42   "Type 42"
-#define FT_XF86_FORMAT_CID       "CID Type 1"
-#define FT_XF86_FORMAT_CFF       "CFF"
-#define FT_XF86_FORMAT_PFR       "PFR"
-#define FT_XF86_FORMAT_WINFNT    "Windows FNT"
+#define FT_FONT_FORMAT_TRUETYPE  "TrueType"
+#define FT_FONT_FORMAT_TYPE_1    "Type 1"
+#define FT_FONT_FORMAT_BDF       "BDF"
+#define FT_FONT_FORMAT_PCF       "PCF"
+#define FT_FONT_FORMAT_TYPE_42   "Type 42"
+#define FT_FONT_FORMAT_CID       "CID Type 1"
+#define FT_FONT_FORMAT_CFF       "CFF"
+#define FT_FONT_FORMAT_PFR       "PFR"
+#define FT_FONT_FORMAT_WINFNT    "Windows FNT"
 
   /* */
 
@@ -49,7 +49,7 @@
 FT_END_HEADER
 
 
-#endif /* __SVXF86NM_H__ */
+#endif /* __SVFNTFMT_H__ */
 
 
 /* END */
diff --git a/include/internal/services/svgldict.h b/include/internal/services/svgldict.h
index 1d12534..f78bca5 100644
--- a/include/internal/services/svgldict.h
+++ b/include/internal/services/svgldict.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph dictionary services (specification).              */
 /*                                                                         */
-/*  Copyright 2003, 2009, 2012 by                                          */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/services/svgxval.h b/include/internal/services/svgxval.h
index 2cdab50..59cc3b7 100644
--- a/include/internal/services/svgxval.h
+++ b/include/internal/services/svgxval.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for validating TrueTypeGX/AAT tables (specification).   */
 /*                                                                         */
-/*  Copyright 2004, 2005 by                                                */
+/*  Copyright 2004-2015 by                                                 */
 /*  Masatake YAMATO, Red Hat K.K.,                                         */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
diff --git a/include/internal/services/svkern.h b/include/internal/services/svkern.h
index 1488adf..bc26f15 100644
--- a/include/internal/services/svkern.h
+++ b/include/internal/services/svkern.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType Kerning service (specification).                        */
 /*                                                                         */
-/*  Copyright 2006 by                                                      */
+/*  Copyright 2006-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/services/svmm.h b/include/internal/services/svmm.h
index b08a663..f2cecfb 100644
--- a/include/internal/services/svmm.h
+++ b/include/internal/services/svmm.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType Multiple Masters and GX var services (specification).   */
 /*                                                                         */
-/*  Copyright 2003, 2004, 2009, 2012 by                                    */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/services/svotval.h b/include/internal/services/svotval.h
index 970bbd5..a82a642 100644
--- a/include/internal/services/svotval.h
+++ b/include/internal/services/svotval.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType OpenType validation service (specification).            */
 /*                                                                         */
-/*  Copyright 2004, 2006 by                                                */
+/*  Copyright 2004-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/services/svpfr.h b/include/internal/services/svpfr.h
index 462786f..d4eb169 100644
--- a/include/internal/services/svpfr.h
+++ b/include/internal/services/svpfr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Internal PFR service functions (specification).                      */
 /*                                                                         */
-/*  Copyright 2003, 2006 by                                                */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/services/svpostnm.h b/include/internal/services/svpostnm.h
index a76b4fe..a89f79e 100644
--- a/include/internal/services/svpostnm.h
+++ b/include/internal/services/svpostnm.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType PostScript name services (specification).               */
 /*                                                                         */
-/*  Copyright 2003, 2007, 2009, 2012 by                                    */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/services/svprop.h b/include/internal/services/svprop.h
index 22da0bb..c9f07ce 100644
--- a/include/internal/services/svprop.h
+++ b/include/internal/services/svprop.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType property service (specification).                       */
 /*                                                                         */
-/*  Copyright 2012 by                                                      */
+/*  Copyright 2012-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/services/svpscmap.h b/include/internal/services/svpscmap.h
index 030948e..66da6e1 100644
--- a/include/internal/services/svpscmap.h
+++ b/include/internal/services/svpscmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType PostScript charmap service (specification).             */
 /*                                                                         */
-/*  Copyright 2003, 2006, 2009, 2012 by                                    */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/services/svpsinfo.h b/include/internal/services/svpsinfo.h
index 4bfb506..752a266 100644
--- a/include/internal/services/svpsinfo.h
+++ b/include/internal/services/svpsinfo.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType PostScript info service (specification).                */
 /*                                                                         */
-/*  Copyright 2003, 2004, 2009, 2011, 2012 by                              */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/services/svsfnt.h b/include/internal/services/svsfnt.h
index d3835aa..252ae1c 100644
--- a/include/internal/services/svsfnt.h
+++ b/include/internal/services/svsfnt.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType SFNT table loading service (specification).             */
 /*                                                                         */
-/*  Copyright 2003, 2004, 2009, 2012 by                                    */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/services/svttcmap.h b/include/internal/services/svttcmap.h
index 4370f4c..4351a9a 100644
--- a/include/internal/services/svttcmap.h
+++ b/include/internal/services/svttcmap.h
@@ -4,10 +4,8 @@
 /*                                                                         */
 /*    The FreeType TrueType/sfnt cmap extra information service.           */
 /*                                                                         */
-/*  Copyright 2003 by                                                      */
-/*  Masatake YAMATO, Redhat K.K.                                           */
-/*                                                                         */
-/*  Copyright 2003, 2008, 2009, 2012, 2013 by                              */
+/*  Copyright 2003-2015 by                                                 */
+/*  Masatake YAMATO, Redhat K.K.,                                          */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/services/svtteng.h b/include/internal/services/svtteng.h
index 58e02a6..272ee8c 100644
--- a/include/internal/services/svtteng.h
+++ b/include/internal/services/svtteng.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType TrueType engine query service (specification).          */
 /*                                                                         */
-/*  Copyright 2006 by                                                      */
+/*  Copyright 2006-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/services/svttglyf.h b/include/internal/services/svttglyf.h
index 369eb84..f5cb76a 100644
--- a/include/internal/services/svttglyf.h
+++ b/include/internal/services/svttglyf.h
@@ -4,7 +4,8 @@
 /*                                                                         */
 /*    The FreeType TrueType glyph service.                                 */
 /*                                                                         */
-/*  Copyright 2007, 2009, 2012 by David Turner.                            */
+/*  Copyright 2007-2015 by                                                 */
+/*  David Turner.                                                          */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
 /*  modified, and distributed under the terms of the FreeType project      */
diff --git a/include/internal/services/svwinfnt.h b/include/internal/services/svwinfnt.h
index 57f7765..0036929 100644
--- a/include/internal/services/svwinfnt.h
+++ b/include/internal/services/svwinfnt.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType Windows FNT/FONT service (specification).               */
 /*                                                                         */
-/*  Copyright 2003 by                                                      */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/internal/sfnt.h b/include/internal/sfnt.h
index 6b5e41f..97ce390 100644
--- a/include/internal/sfnt.h
+++ b/include/internal/sfnt.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level `sfnt' driver interface (specification).                  */
 /*                                                                         */
-/*  Copyright 1996-2006, 2009, 2012-2013 by                                */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -405,14 +405,18 @@
   /* <Input>                                                               */
   /*    face     :: A handle to the target face object.                    */
   /*                                                                       */
-  /*    stream   :: The input stream.                                      */
-  /*                                                                       */
   /*    vertical :: A boolean flag.  If set, load vertical metrics.        */
   /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    gindex   :: The glyph index.                                       */
   /*                                                                       */
-  typedef FT_Error
+  /* <Output>                                                              */
+  /*    abearing :: The horizontal (or vertical) bearing.  Set to zero in  */
+  /*                case of error.                                         */
+  /*                                                                       */
+  /*    aadvance :: The horizontal (or vertical) advance.  Set to zero in  */
+  /*                case of error.                                         */
+  /*                                                                       */
+  typedef void
   (*TT_Get_Metrics_Func)( TT_Face     face,
                           FT_Bool     vertical,
                           FT_UInt     gindex,
diff --git a/include/internal/t1types.h b/include/internal/t1types.h
index e20237c..029acc4 100644
--- a/include/internal/t1types.h
+++ b/include/internal/t1types.h
@@ -5,7 +5,7 @@
 /*    Basic Type1/Type2 type definitions and interface (specification      */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 1996-2004, 2006, 2008, 2009, 2011, 2013 by                   */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -106,12 +106,12 @@
 
     FT_Int           num_subrs;
     FT_Byte**        subrs;
-    FT_PtrDist*      subrs_len;
+    FT_UInt*         subrs_len;
 
     FT_Int           num_glyphs;
     FT_String**      glyph_names;       /* array of glyph names       */
     FT_Byte**        charstrings;       /* array of glyph charstrings */
-    FT_PtrDist*      charstrings_len;
+    FT_UInt*         charstrings_len;
 
     FT_Byte          paint_type;
     FT_Byte          font_type;
@@ -127,7 +127,7 @@
 
   typedef struct  CID_SubrsRec_
   {
-    FT_UInt    num_subrs;
+    FT_Int     num_subrs;
     FT_Byte**  code;
 
   } CID_SubrsRec, *CID_Subrs;
@@ -157,10 +157,10 @@
 
   typedef struct  AFM_KernPairRec_
   {
-    FT_Int  index1;
-    FT_Int  index2;
-    FT_Int  x;
-    FT_Int  y;
+    FT_UInt  index1;
+    FT_UInt  index2;
+    FT_Int   x;
+    FT_Int   y;
 
   } AFM_KernPairRec, *AFM_KernPair;
 
@@ -171,9 +171,9 @@
     FT_Fixed       Ascender;
     FT_Fixed       Descender;
     AFM_TrackKern  TrackKerns;   /* free if non-NULL */
-    FT_Int         NumTrackKern;
+    FT_UInt        NumTrackKern;
     AFM_KernPair   KernPairs;    /* free if non-NULL */
-    FT_Int         NumKernPair;
+    FT_UInt        NumKernPair;
 
   } AFM_FontInfoRec, *AFM_FontInfo;
 
diff --git a/include/internal/tttypes.h b/include/internal/tttypes.h
index ad302b8..31dd0aa 100644
--- a/include/internal/tttypes.h
+++ b/include/internal/tttypes.h
@@ -5,7 +5,7 @@
 /*    Basic SFNT/TrueType type definitions and interface (specification    */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 1996-2002, 2004-2008, 2012-2013 by                           */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -614,8 +614,7 @@
   /*                       in use by other platforms (e.g. Newton).        */
   /*                       For details, please see                         */
   /*                                                                       */
-  /*                         http://fonts.apple.com/                       */
-  /*                                TTRefMan/RM06/Chap6bloc.html           */
+  /*                         https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bloc.html */
   /*                                                                       */
   /*   hori             :: The line metrics for horizontal layouts.        */
   /*                                                                       */
@@ -635,8 +634,7 @@
   /*   flags            :: Is this a vertical or horizontal strike?  For   */
   /*                       details, please see                             */
   /*                                                                       */
-  /*                         http://fonts.apple.com/                       */
-  /*                                TTRefMan/RM06/Chap6bloc.html           */
+  /*                         https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6bloc.html */
   /*                                                                       */
   typedef struct  TT_SBit_StrikeRec_
   {
@@ -1113,7 +1111,7 @@
   /*                            This field also contains the associated    */
   /*                            vertical metrics table (`vmtx'), if found. */
   /*                            IMPORTANT: The contents of this field is   */
-  /*                            undefined if the `verticalInfo' field is   */
+  /*                            undefined if the `vertical_info' field is  */
   /*                            unset.                                     */
   /*                                                                       */
   /*    num_names            :: The number of name records within this     */
@@ -1440,7 +1438,7 @@
   {
     FT_Memory   memory;
     FT_UShort   max_points;
-    FT_UShort   max_contours;
+    FT_Short    max_contours;
     FT_UShort   n_points;    /* number of points in zone    */
     FT_Short    n_contours;  /* number of contours          */
 
diff --git a/include/t1tables.h b/include/t1tables.h
index a14255e..a6ea415 100644
--- a/include/t1tables.h
+++ b/include/t1tables.h
@@ -5,7 +5,7 @@
 /*    Basic Type 1/Type 2 tables definitions and interface (specification  */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 1996-2004, 2006, 2008, 2009, 2011 by                         */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -49,6 +49,26 @@
   /*    This section contains the definition of Type 1-specific tables,    */
   /*    including structures related to other PostScript font formats.     */
   /*                                                                       */
+  /* <Order>                                                               */
+  /*    PS_FontInfoRec                                                     */
+  /*    PS_FontInfo                                                        */
+  /*    PS_PrivateRec                                                      */
+  /*    PS_Private                                                         */
+  /*                                                                       */
+  /*    CID_FaceDictRec                                                    */
+  /*    CID_FaceDict                                                       */
+  /*    CID_FaceInfoRec                                                    */
+  /*    CID_FaceInfo                                                       */
+  /*                                                                       */
+  /*    FT_Has_PS_Glyph_Names                                              */
+  /*    FT_Get_PS_Font_Info                                                */
+  /*    FT_Get_PS_Font_Private                                             */
+  /*    FT_Get_PS_Font_Value                                               */
+  /*                                                                       */
+  /*    T1_Blend_Flags                                                     */
+  /*    T1_EncodingType                                                    */
+  /*    PS_Dict_Keys                                                       */
+  /*                                                                       */
   /*************************************************************************/
 
 
@@ -190,14 +210,30 @@
   /*    given blend dictionary (font info or private).  Used to support    */
   /*    Multiple Masters fonts.                                            */
   /*                                                                       */
+  /* <Values>                                                              */
+  /*    T1_BLEND_UNDERLINE_POSITION ::                                     */
+  /*    T1_BLEND_UNDERLINE_THICKNESS ::                                    */
+  /*    T1_BLEND_ITALIC_ANGLE ::                                           */
+  /*    T1_BLEND_BLUE_VALUES ::                                            */
+  /*    T1_BLEND_OTHER_BLUES ::                                            */
+  /*    T1_BLEND_STANDARD_WIDTH ::                                         */
+  /*    T1_BLEND_STANDARD_HEIGHT ::                                        */
+  /*    T1_BLEND_STEM_SNAP_WIDTHS ::                                       */
+  /*    T1_BLEND_STEM_SNAP_HEIGHTS ::                                      */
+  /*    T1_BLEND_BLUE_SCALE ::                                             */
+  /*    T1_BLEND_BLUE_SHIFT ::                                             */
+  /*    T1_BLEND_FAMILY_BLUES ::                                           */
+  /*    T1_BLEND_FAMILY_OTHER_BLUES ::                                     */
+  /*    T1_BLEND_FORCE_BOLD ::                                             */
+  /*                                                                       */
   typedef enum  T1_Blend_Flags_
   {
-    /*# required fields in a FontInfo blend dictionary */
+    /* required fields in a FontInfo blend dictionary */
     T1_BLEND_UNDERLINE_POSITION = 0,
     T1_BLEND_UNDERLINE_THICKNESS,
     T1_BLEND_ITALIC_ANGLE,
 
-    /*# required fields in a Private blend dictionary */
+    /* required fields in a Private blend dictionary */
     T1_BLEND_BLUE_VALUES,
     T1_BLEND_OTHER_BLUES,
     T1_BLEND_STANDARD_WIDTH,
@@ -210,15 +246,13 @@
     T1_BLEND_FAMILY_OTHER_BLUES,
     T1_BLEND_FORCE_BOLD,
 
-    /*# never remove */
-    T1_BLEND_MAX
+    T1_BLEND_MAX    /* do not remove */
 
   } T1_Blend_Flags;
 
-  /* */
 
-
-  /*# backwards compatible definitions */
+  /* these constants are deprecated; use the corresponding */
+  /* `T1_Blend_Flags' values instead                       */
 #define t1_blend_underline_position   T1_BLEND_UNDERLINE_POSITION
 #define t1_blend_underline_thickness  T1_BLEND_UNDERLINE_THICKNESS
 #define t1_blend_italic_angle         T1_BLEND_ITALIC_ANGLE
@@ -235,6 +269,8 @@
 #define t1_blend_force_bold           T1_BLEND_FORCE_BOLD
 #define t1_blend_max                  T1_BLEND_MAX
 
+  /* */
+
 
   /* maximum number of Multiple Masters designs, as defined in the spec */
 #define T1_MAX_MM_DESIGNS     16
@@ -333,10 +369,17 @@
   /*                                                                       */
   typedef struct CID_FaceDictRec_*  CID_FaceDict;
 
-  /* */
 
-
-  /* backwards-compatible definition */
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    CID_FontDict                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This type is equivalent to @CID_FaceDictRec.  It is deprecated but */
+  /*    kept to maintain source compatibility between various versions of  */
+  /*    FreeType.                                                          */
+  /*                                                                       */
   typedef CID_FaceDictRec  CID_FontDict;
 
 
@@ -449,8 +492,9 @@
    *    FreeType error code.  0~means success.
    *
    * @note:
-   *    The string pointers within the font info structure are owned by
-   *    the face and don't need to be freed by the caller.
+   *    String pointers within the @PS_FontInfoRec structure are owned by
+   *    the face and don't need to be freed by the caller.  Missing entries
+   *    in the font's FontInfo dictionary are represented by NULL pointers.
    *
    *    If the font's format is not PostScript-based, this function will
    *    return the `FT_Err_Invalid_Argument' error code.
@@ -503,6 +547,13 @@
   /*    An enumeration describing the `Encoding' entry in a Type 1         */
   /*    dictionary.                                                        */
   /*                                                                       */
+  /* <Values>                                                              */
+  /*    T1_ENCODING_TYPE_NONE ::                                           */
+  /*    T1_ENCODING_TYPE_ARRAY ::                                          */
+  /*    T1_ENCODING_TYPE_STANDARD ::                                       */
+  /*    T1_ENCODING_TYPE_ISOLATIN1 ::                                      */
+  /*    T1_ENCODING_TYPE_EXPERT ::                                         */
+  /*                                                                       */
   typedef enum  T1_EncodingType_
   {
     T1_ENCODING_TYPE_NONE = 0,
@@ -523,6 +574,54 @@
   /*    An enumeration used in calls to @FT_Get_PS_Font_Value to identify  */
   /*    the Type~1 dictionary entry to retrieve.                           */
   /*                                                                       */
+  /* <Values>                                                              */
+  /*    PS_DICT_FONT_TYPE ::                                               */
+  /*    PS_DICT_FONT_MATRIX ::                                             */
+  /*    PS_DICT_FONT_BBOX ::                                               */
+  /*    PS_DICT_PAINT_TYPE ::                                              */
+  /*    PS_DICT_FONT_NAME ::                                               */
+  /*    PS_DICT_UNIQUE_ID ::                                               */
+  /*    PS_DICT_NUM_CHAR_STRINGS ::                                        */
+  /*    PS_DICT_CHAR_STRING_KEY ::                                         */
+  /*    PS_DICT_CHAR_STRING ::                                             */
+  /*    PS_DICT_ENCODING_TYPE ::                                           */
+  /*    PS_DICT_ENCODING_ENTRY ::                                          */
+  /*    PS_DICT_NUM_SUBRS ::                                               */
+  /*    PS_DICT_SUBR ::                                                    */
+  /*    PS_DICT_STD_HW ::                                                  */
+  /*    PS_DICT_STD_VW ::                                                  */
+  /*    PS_DICT_NUM_BLUE_VALUES ::                                         */
+  /*    PS_DICT_BLUE_VALUE ::                                              */
+  /*    PS_DICT_BLUE_FUZZ ::                                               */
+  /*    PS_DICT_NUM_OTHER_BLUES ::                                         */
+  /*    PS_DICT_OTHER_BLUE ::                                              */
+  /*    PS_DICT_NUM_FAMILY_BLUES ::                                        */
+  /*    PS_DICT_FAMILY_BLUE ::                                             */
+  /*    PS_DICT_NUM_FAMILY_OTHER_BLUES ::                                  */
+  /*    PS_DICT_FAMILY_OTHER_BLUE ::                                       */
+  /*    PS_DICT_BLUE_SCALE ::                                              */
+  /*    PS_DICT_BLUE_SHIFT ::                                              */
+  /*    PS_DICT_NUM_STEM_SNAP_H ::                                         */
+  /*    PS_DICT_STEM_SNAP_H ::                                             */
+  /*    PS_DICT_NUM_STEM_SNAP_V ::                                         */
+  /*    PS_DICT_STEM_SNAP_V ::                                             */
+  /*    PS_DICT_FORCE_BOLD ::                                              */
+  /*    PS_DICT_RND_STEM_UP ::                                             */
+  /*    PS_DICT_MIN_FEATURE ::                                             */
+  /*    PS_DICT_LEN_IV ::                                                  */
+  /*    PS_DICT_PASSWORD ::                                                */
+  /*    PS_DICT_LANGUAGE_GROUP ::                                          */
+  /*    PS_DICT_VERSION ::                                                 */
+  /*    PS_DICT_NOTICE ::                                                  */
+  /*    PS_DICT_FULL_NAME ::                                               */
+  /*    PS_DICT_FAMILY_NAME ::                                             */
+  /*    PS_DICT_WEIGHT ::                                                  */
+  /*    PS_DICT_IS_FIXED_PITCH ::                                          */
+  /*    PS_DICT_UNDERLINE_POSITION ::                                      */
+  /*    PS_DICT_UNDERLINE_THICKNESS ::                                     */
+  /*    PS_DICT_FS_TYPE ::                                                 */
+  /*    PS_DICT_ITALIC_ANGLE ::                                            */
+  /*                                                                       */
   typedef enum  PS_Dict_Keys_
   {
     /* conventionally in the font dictionary */
diff --git a/include/ttnameid.h b/include/ttnameid.h
index 9711d1d..c9585f2 100644
--- a/include/ttnameid.h
+++ b/include/ttnameid.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType name ID definitions (specification only).                   */
 /*                                                                         */
-/*  Copyright 1996-2004, 2006-2008, 2012, 2013 by                          */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -321,7 +321,7 @@
   /*                                                                       */
   /* The canonical source for the Apple assigned Language ID's is at       */
   /*                                                                       */
-  /*   https://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html      */
+  /*   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html */
   /*                                                                       */
 #define TT_MAC_LANGID_ENGLISH                       0
 #define TT_MAC_LANGID_FRENCH                        1
@@ -470,26 +470,26 @@
 #define TT_MS_LANGID_ARABIC_GENERAL                    0x0001
 #define TT_MS_LANGID_ARABIC_SAUDI_ARABIA               0x0401
 #define TT_MS_LANGID_ARABIC_IRAQ                       0x0801
-#define TT_MS_LANGID_ARABIC_EGYPT                      0x0c01
+#define TT_MS_LANGID_ARABIC_EGYPT                      0x0C01
 #define TT_MS_LANGID_ARABIC_LIBYA                      0x1001
 #define TT_MS_LANGID_ARABIC_ALGERIA                    0x1401
 #define TT_MS_LANGID_ARABIC_MOROCCO                    0x1801
-#define TT_MS_LANGID_ARABIC_TUNISIA                    0x1c01
+#define TT_MS_LANGID_ARABIC_TUNISIA                    0x1C01
 #define TT_MS_LANGID_ARABIC_OMAN                       0x2001
 #define TT_MS_LANGID_ARABIC_YEMEN                      0x2401
 #define TT_MS_LANGID_ARABIC_SYRIA                      0x2801
-#define TT_MS_LANGID_ARABIC_JORDAN                     0x2c01
+#define TT_MS_LANGID_ARABIC_JORDAN                     0x2C01
 #define TT_MS_LANGID_ARABIC_LEBANON                    0x3001
 #define TT_MS_LANGID_ARABIC_KUWAIT                     0x3401
 #define TT_MS_LANGID_ARABIC_UAE                        0x3801
-#define TT_MS_LANGID_ARABIC_BAHRAIN                    0x3c01
+#define TT_MS_LANGID_ARABIC_BAHRAIN                    0x3C01
 #define TT_MS_LANGID_ARABIC_QATAR                      0x4001
 #define TT_MS_LANGID_BULGARIAN_BULGARIA                0x0402
 #define TT_MS_LANGID_CATALAN_SPAIN                     0x0403
 #define TT_MS_LANGID_CHINESE_GENERAL                   0x0004
 #define TT_MS_LANGID_CHINESE_TAIWAN                    0x0404
 #define TT_MS_LANGID_CHINESE_PRC                       0x0804
-#define TT_MS_LANGID_CHINESE_HONG_KONG                 0x0c04
+#define TT_MS_LANGID_CHINESE_HONG_KONG                 0x0C04
 #define TT_MS_LANGID_CHINESE_SINGAPORE                 0x1004
 
 #if 1  /* this looks like the correct value */
@@ -507,7 +507,7 @@
 #define TT_MS_LANGID_DANISH_DENMARK                    0x0406
 #define TT_MS_LANGID_GERMAN_GERMANY                    0x0407
 #define TT_MS_LANGID_GERMAN_SWITZERLAND                0x0807
-#define TT_MS_LANGID_GERMAN_AUSTRIA                    0x0c07
+#define TT_MS_LANGID_GERMAN_AUSTRIA                    0x0C07
 #define TT_MS_LANGID_GERMAN_LUXEMBOURG                 0x1007
 #define TT_MS_LANGID_GERMAN_LIECHTENSTEI               0x1407
 #define TT_MS_LANGID_GREEK_GREECE                      0x0408
@@ -520,69 +520,69 @@
 #define TT_MS_LANGID_ENGLISH_GENERAL                   0x0009
 #define TT_MS_LANGID_ENGLISH_UNITED_STATES             0x0409
 #define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM            0x0809
-#define TT_MS_LANGID_ENGLISH_AUSTRALIA                 0x0c09
+#define TT_MS_LANGID_ENGLISH_AUSTRALIA                 0x0C09
 #define TT_MS_LANGID_ENGLISH_CANADA                    0x1009
 #define TT_MS_LANGID_ENGLISH_NEW_ZEALAND               0x1409
 #define TT_MS_LANGID_ENGLISH_IRELAND                   0x1809
-#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA              0x1c09
+#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA              0x1C09
 #define TT_MS_LANGID_ENGLISH_JAMAICA                   0x2009
 #define TT_MS_LANGID_ENGLISH_CARIBBEAN                 0x2409
 #define TT_MS_LANGID_ENGLISH_BELIZE                    0x2809
-#define TT_MS_LANGID_ENGLISH_TRINIDAD                  0x2c09
+#define TT_MS_LANGID_ENGLISH_TRINIDAD                  0x2C09
 #define TT_MS_LANGID_ENGLISH_ZIMBABWE                  0x3009
 #define TT_MS_LANGID_ENGLISH_PHILIPPINES               0x3409
 #define TT_MS_LANGID_ENGLISH_INDONESIA                 0x3809
-#define TT_MS_LANGID_ENGLISH_HONG_KONG                 0x3c09
+#define TT_MS_LANGID_ENGLISH_HONG_KONG                 0x3C09
 #define TT_MS_LANGID_ENGLISH_INDIA                     0x4009
 #define TT_MS_LANGID_ENGLISH_MALAYSIA                  0x4409
 #define TT_MS_LANGID_ENGLISH_SINGAPORE                 0x4809
-#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT    0x040a
-#define TT_MS_LANGID_SPANISH_MEXICO                    0x080a
-#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT  0x0c0a
-#define TT_MS_LANGID_SPANISH_GUATEMALA                 0x100a
-#define TT_MS_LANGID_SPANISH_COSTA_RICA                0x140a
-#define TT_MS_LANGID_SPANISH_PANAMA                    0x180a
-#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC        0x1c0a
-#define TT_MS_LANGID_SPANISH_VENEZUELA                 0x200a
-#define TT_MS_LANGID_SPANISH_COLOMBIA                  0x240a
-#define TT_MS_LANGID_SPANISH_PERU                      0x280a
-#define TT_MS_LANGID_SPANISH_ARGENTINA                 0x2c0a
-#define TT_MS_LANGID_SPANISH_ECUADOR                   0x300a
-#define TT_MS_LANGID_SPANISH_CHILE                     0x340a
-#define TT_MS_LANGID_SPANISH_URUGUAY                   0x380a
-#define TT_MS_LANGID_SPANISH_PARAGUAY                  0x3c0a
-#define TT_MS_LANGID_SPANISH_BOLIVIA                   0x400a
-#define TT_MS_LANGID_SPANISH_EL_SALVADOR               0x440a
-#define TT_MS_LANGID_SPANISH_HONDURAS                  0x480a
-#define TT_MS_LANGID_SPANISH_NICARAGUA                 0x4c0a
-#define TT_MS_LANGID_SPANISH_PUERTO_RICO               0x500a
-#define TT_MS_LANGID_SPANISH_UNITED_STATES             0x540a
+#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT    0x040A
+#define TT_MS_LANGID_SPANISH_MEXICO                    0x080A
+#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT  0x0C0A
+#define TT_MS_LANGID_SPANISH_GUATEMALA                 0x100A
+#define TT_MS_LANGID_SPANISH_COSTA_RICA                0x140A
+#define TT_MS_LANGID_SPANISH_PANAMA                    0x180A
+#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC        0x1C0A
+#define TT_MS_LANGID_SPANISH_VENEZUELA                 0x200A
+#define TT_MS_LANGID_SPANISH_COLOMBIA                  0x240A
+#define TT_MS_LANGID_SPANISH_PERU                      0x280A
+#define TT_MS_LANGID_SPANISH_ARGENTINA                 0x2C0A
+#define TT_MS_LANGID_SPANISH_ECUADOR                   0x300A
+#define TT_MS_LANGID_SPANISH_CHILE                     0x340A
+#define TT_MS_LANGID_SPANISH_URUGUAY                   0x380A
+#define TT_MS_LANGID_SPANISH_PARAGUAY                  0x3C0A
+#define TT_MS_LANGID_SPANISH_BOLIVIA                   0x400A
+#define TT_MS_LANGID_SPANISH_EL_SALVADOR               0x440A
+#define TT_MS_LANGID_SPANISH_HONDURAS                  0x480A
+#define TT_MS_LANGID_SPANISH_NICARAGUA                 0x4C0A
+#define TT_MS_LANGID_SPANISH_PUERTO_RICO               0x500A
+#define TT_MS_LANGID_SPANISH_UNITED_STATES             0x540A
   /* The following ID blatantly violate MS specs by using a */
   /* sublanguage > 0x1F.                                    */
-#define TT_MS_LANGID_SPANISH_LATIN_AMERICA             0xE40aU
-#define TT_MS_LANGID_FINNISH_FINLAND                   0x040b
-#define TT_MS_LANGID_FRENCH_FRANCE                     0x040c
-#define TT_MS_LANGID_FRENCH_BELGIUM                    0x080c
-#define TT_MS_LANGID_FRENCH_CANADA                     0x0c0c
-#define TT_MS_LANGID_FRENCH_SWITZERLAND                0x100c
-#define TT_MS_LANGID_FRENCH_LUXEMBOURG                 0x140c
-#define TT_MS_LANGID_FRENCH_MONACO                     0x180c
-#define TT_MS_LANGID_FRENCH_WEST_INDIES                0x1c0c
-#define TT_MS_LANGID_FRENCH_REUNION                    0x200c
-#define TT_MS_LANGID_FRENCH_CONGO                      0x240c
+#define TT_MS_LANGID_SPANISH_LATIN_AMERICA             0xE40AU
+#define TT_MS_LANGID_FINNISH_FINLAND                   0x040B
+#define TT_MS_LANGID_FRENCH_FRANCE                     0x040C
+#define TT_MS_LANGID_FRENCH_BELGIUM                    0x080C
+#define TT_MS_LANGID_FRENCH_CANADA                     0x0C0C
+#define TT_MS_LANGID_FRENCH_SWITZERLAND                0x100C
+#define TT_MS_LANGID_FRENCH_LUXEMBOURG                 0x140C
+#define TT_MS_LANGID_FRENCH_MONACO                     0x180C
+#define TT_MS_LANGID_FRENCH_WEST_INDIES                0x1C0C
+#define TT_MS_LANGID_FRENCH_REUNION                    0x200C
+#define TT_MS_LANGID_FRENCH_CONGO                      0x240C
   /* which was formerly: */
 #define TT_MS_LANGID_FRENCH_ZAIRE  TT_MS_LANGID_FRENCH_CONGO
-#define TT_MS_LANGID_FRENCH_SENEGAL                    0x280c
-#define TT_MS_LANGID_FRENCH_CAMEROON                   0x2c0c
-#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE              0x300c
-#define TT_MS_LANGID_FRENCH_MALI                       0x340c
-#define TT_MS_LANGID_FRENCH_MOROCCO                    0x380c
-#define TT_MS_LANGID_FRENCH_HAITI                      0x3c0c
-  /* and another violation of the spec (see 0xE40aU) */
-#define TT_MS_LANGID_FRENCH_NORTH_AFRICA               0xE40cU
-#define TT_MS_LANGID_HEBREW_ISRAEL                     0x040d
-#define TT_MS_LANGID_HUNGARIAN_HUNGARY                 0x040e
-#define TT_MS_LANGID_ICELANDIC_ICELAND                 0x040f
+#define TT_MS_LANGID_FRENCH_SENEGAL                    0x280C
+#define TT_MS_LANGID_FRENCH_CAMEROON                   0x2C0C
+#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE              0x300C
+#define TT_MS_LANGID_FRENCH_MALI                       0x340C
+#define TT_MS_LANGID_FRENCH_MOROCCO                    0x380C
+#define TT_MS_LANGID_FRENCH_HAITI                      0x3C0C
+  /* and another violation of the spec (see 0xE40AU) */
+#define TT_MS_LANGID_FRENCH_NORTH_AFRICA               0xE40CU
+#define TT_MS_LANGID_HEBREW_ISRAEL                     0x040D
+#define TT_MS_LANGID_HUNGARIAN_HUNGARY                 0x040E
+#define TT_MS_LANGID_ICELANDIC_ICELAND                 0x040F
 #define TT_MS_LANGID_ITALIAN_ITALY                     0x0410
 #define TT_MS_LANGID_ITALIAN_SWITZERLAND               0x0810
 #define TT_MS_LANGID_JAPANESE_JAPAN                    0x0411
@@ -600,27 +600,27 @@
 #define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA                0x0818
 #define TT_MS_LANGID_RUSSIAN_RUSSIA                    0x0419
 #define TT_MS_LANGID_RUSSIAN_MOLDAVIA                  0x0819
-#define TT_MS_LANGID_CROATIAN_CROATIA                  0x041a
-#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN              0x081a
-#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC           0x0c1a
+#define TT_MS_LANGID_CROATIAN_CROATIA                  0x041A
+#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN              0x081A
+#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC           0x0C1A
 
 #if 0  /* this used to be this value, but it looks like we were wrong */
-#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA        0x101a
+#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA        0x101A
 #else  /* current sources say */
-#define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA       0x101a
-#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA        0x141a
+#define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA       0x101A
+#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA        0x141A
        /* and XPsp2 Platform SDK added (2004-07-26) */
        /* Names are shortened to be significant within 40 chars. */
-#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN         0x181a
-#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC      0x181a
+#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN         0x181A
+#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC      0x181A
 #endif
 
-#define TT_MS_LANGID_SLOVAK_SLOVAKIA                   0x041b
-#define TT_MS_LANGID_ALBANIAN_ALBANIA                  0x041c
-#define TT_MS_LANGID_SWEDISH_SWEDEN                    0x041d
-#define TT_MS_LANGID_SWEDISH_FINLAND                   0x081d
-#define TT_MS_LANGID_THAI_THAILAND                     0x041e
-#define TT_MS_LANGID_TURKISH_TURKEY                    0x041f
+#define TT_MS_LANGID_SLOVAK_SLOVAKIA                   0x041B
+#define TT_MS_LANGID_ALBANIAN_ALBANIA                  0x041C
+#define TT_MS_LANGID_SWEDISH_SWEDEN                    0x041D
+#define TT_MS_LANGID_SWEDISH_FINLAND                   0x081D
+#define TT_MS_LANGID_THAI_THAILAND                     0x041E
+#define TT_MS_LANGID_TURKISH_TURKEY                    0x041F
 #define TT_MS_LANGID_URDU_PAKISTAN                     0x0420
 #define TT_MS_LANGID_URDU_INDIA                        0x0820
 #define TT_MS_LANGID_INDONESIAN_INDONESIA              0x0421
@@ -633,13 +633,13 @@
 #define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA      0x0827
 #define TT_MS_LANGID_TAJIK_TAJIKISTAN                  0x0428
 #define TT_MS_LANGID_FARSI_IRAN                        0x0429
-#define TT_MS_LANGID_VIETNAMESE_VIET_NAM               0x042a
-#define TT_MS_LANGID_ARMENIAN_ARMENIA                  0x042b
-#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN            0x042c
-#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC         0x082c
-#define TT_MS_LANGID_BASQUE_SPAIN                      0x042d
-#define TT_MS_LANGID_SORBIAN_GERMANY                   0x042e
-#define TT_MS_LANGID_MACEDONIAN_MACEDONIA              0x042f
+#define TT_MS_LANGID_VIETNAMESE_VIET_NAM               0x042A
+#define TT_MS_LANGID_ARMENIAN_ARMENIA                  0x042B
+#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN            0x042C
+#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC         0x082C
+#define TT_MS_LANGID_BASQUE_SPAIN                      0x042D
+#define TT_MS_LANGID_SORBIAN_GERMANY                   0x042E
+#define TT_MS_LANGID_MACEDONIAN_MACEDONIA              0x042F
 #define TT_MS_LANGID_SUTU_SOUTH_AFRICA                 0x0430
 #define TT_MS_LANGID_TSONGA_SOUTH_AFRICA               0x0431
 #define TT_MS_LANGID_TSWANA_SOUTH_AFRICA               0x0432
@@ -650,32 +650,32 @@
 #define TT_MS_LANGID_GEORGIAN_GEORGIA                  0x0437
 #define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS           0x0438
 #define TT_MS_LANGID_HINDI_INDIA                       0x0439
-#define TT_MS_LANGID_MALTESE_MALTA                     0x043a
+#define TT_MS_LANGID_MALTESE_MALTA                     0x043A
   /* Added by XPsp2 Platform SDK (2004-07-26) */
-#define TT_MS_LANGID_SAMI_NORTHERN_NORWAY              0x043b
-#define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN              0x083b
-#define TT_MS_LANGID_SAMI_NORTHERN_FINLAND             0x0C3b
-#define TT_MS_LANGID_SAMI_LULE_NORWAY                  0x103b
-#define TT_MS_LANGID_SAMI_LULE_SWEDEN                  0x143b
-#define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY              0x183b
-#define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN              0x1C3b
-#define TT_MS_LANGID_SAMI_SKOLT_FINLAND                0x203b
-#define TT_MS_LANGID_SAMI_INARI_FINLAND                0x243b
+#define TT_MS_LANGID_SAMI_NORTHERN_NORWAY              0x043B
+#define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN              0x083B
+#define TT_MS_LANGID_SAMI_NORTHERN_FINLAND             0x0C3B
+#define TT_MS_LANGID_SAMI_LULE_NORWAY                  0x103B
+#define TT_MS_LANGID_SAMI_LULE_SWEDEN                  0x143B
+#define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY              0x183B
+#define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN              0x1C3B
+#define TT_MS_LANGID_SAMI_SKOLT_FINLAND                0x203B
+#define TT_MS_LANGID_SAMI_INARI_FINLAND                0x243B
   /* ... and we also keep our old identifier... */
-#define TT_MS_LANGID_SAAMI_LAPONIA                     0x043b
+#define TT_MS_LANGID_SAAMI_LAPONIA                     0x043B
 
 #if 0 /* this seems to be a previous inversion */
-#define TT_MS_LANGID_IRISH_GAELIC_IRELAND              0x043c
-#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM    0x083c
+#define TT_MS_LANGID_IRISH_GAELIC_IRELAND              0x043C
+#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM    0x083C
 #else
-#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM    0x083c
-#define TT_MS_LANGID_IRISH_GAELIC_IRELAND              0x043c
+#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM    0x083C
+#define TT_MS_LANGID_IRISH_GAELIC_IRELAND              0x043C
 #endif
 
-#define TT_MS_LANGID_YIDDISH_GERMANY                   0x043d
-#define TT_MS_LANGID_MALAY_MALAYSIA                    0x043e
-#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM           0x083e
-#define TT_MS_LANGID_KAZAK_KAZAKSTAN                   0x043f
+#define TT_MS_LANGID_YIDDISH_GERMANY                   0x043D
+#define TT_MS_LANGID_MALAY_MALAYSIA                    0x043E
+#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM           0x083E
+#define TT_MS_LANGID_KAZAK_KAZAKSTAN                   0x043F
 #define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN /* Cyrillic*/ 0x0440
   /* alias declared in Windows 2000 */
 #define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \
@@ -693,12 +693,12 @@
 #define TT_MS_LANGID_GUJARATI_INDIA                    0x0447
 #define TT_MS_LANGID_ORIYA_INDIA                       0x0448
 #define TT_MS_LANGID_TAMIL_INDIA                       0x0449
-#define TT_MS_LANGID_TELUGU_INDIA                      0x044a
-#define TT_MS_LANGID_KANNADA_INDIA                     0x044b
-#define TT_MS_LANGID_MALAYALAM_INDIA                   0x044c
-#define TT_MS_LANGID_ASSAMESE_INDIA                    0x044d
-#define TT_MS_LANGID_MARATHI_INDIA                     0x044e
-#define TT_MS_LANGID_SANSKRIT_INDIA                    0x044f
+#define TT_MS_LANGID_TELUGU_INDIA                      0x044A
+#define TT_MS_LANGID_KANNADA_INDIA                     0x044B
+#define TT_MS_LANGID_MALAYALAM_INDIA                   0x044C
+#define TT_MS_LANGID_ASSAMESE_INDIA                    0x044D
+#define TT_MS_LANGID_MARATHI_INDIA                     0x044E
+#define TT_MS_LANGID_SANSKRIT_INDIA                    0x044F
 #define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450
 #define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN      0x0850
 #define TT_MS_LANGID_TIBETAN_CHINA                     0x0451
@@ -732,13 +732,13 @@
 #define TT_MS_LANGID_SINDHI_INDIA /* Arabic */         0x0459
 #define TT_MS_LANGID_SINDHI_PAKISTAN                   0x0859
   /* Missing a LCID for Sindhi in Devanagari script */
-#define TT_MS_LANGID_SYRIAC_SYRIA                      0x045a
-#define TT_MS_LANGID_SINHALESE_SRI_LANKA               0x045b
-#define TT_MS_LANGID_CHEROKEE_UNITED_STATES            0x045c
-#define TT_MS_LANGID_INUKTITUT_CANADA                  0x045d
-#define TT_MS_LANGID_AMHARIC_ETHIOPIA                  0x045e
-#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */    0x045f
-#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN           0x085f
+#define TT_MS_LANGID_SYRIAC_SYRIA                      0x045A
+#define TT_MS_LANGID_SINHALESE_SRI_LANKA               0x045B
+#define TT_MS_LANGID_CHEROKEE_UNITED_STATES            0x045C
+#define TT_MS_LANGID_INUKTITUT_CANADA                  0x045D
+#define TT_MS_LANGID_AMHARIC_ETHIOPIA                  0x045E
+#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */    0x045F
+#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN           0x085F
   /* Missing a LCID for Tifinagh script */
 #define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */    0x0460
   /* Spelled this way by XPsp2 Platform SDK (2004-07-26) */
@@ -758,15 +758,15 @@
 #define TT_MS_LANGID_FULFULDE_NIGERIA                  0x0467
 #define TT_MS_LANGID_HAUSA_NIGERIA                     0x0468
 #define TT_MS_LANGID_IBIBIO_NIGERIA                    0x0469
-#define TT_MS_LANGID_YORUBA_NIGERIA                    0x046a
-#define TT_MS_LANGID_QUECHUA_BOLIVIA                   0x046b
-#define TT_MS_LANGID_QUECHUA_ECUADOR                   0x086b
-#define TT_MS_LANGID_QUECHUA_PERU                      0x0c6b
-#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA               0x046c
+#define TT_MS_LANGID_YORUBA_NIGERIA                    0x046A
+#define TT_MS_LANGID_QUECHUA_BOLIVIA                   0x046B
+#define TT_MS_LANGID_QUECHUA_ECUADOR                   0x086B
+#define TT_MS_LANGID_QUECHUA_PERU                      0x0C6B
+#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA               0x046C
   /* Also spelled by XPsp2 Platform SDK (2004-07-26) */
 #define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \
           TT_MS_LANGID_SEPEDI_SOUTH_AFRICA
-  /* language codes 0x046d, 0x046e and 0x046f are (still) unknown. */
+  /* language codes 0x046D, 0x046E and 0x046F are (still) unknown. */
 #define TT_MS_LANGID_IGBO_NIGERIA                      0x0470
 #define TT_MS_LANGID_KANURI_NIGERIA                    0x0471
 #define TT_MS_LANGID_OROMO_ETHIOPIA                    0x0472
@@ -783,12 +783,12 @@
   /*       studying).                                                     */
 #define TT_MS_LANGID_YI_CHINA                          0x0478
 #define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES   0x0479
-  /* language codes from 0x047a to 0x047f are (still) unknown. */
+  /* language codes from 0x047A to 0x047F are (still) unknown. */
 #define TT_MS_LANGID_UIGHUR_CHINA                      0x0480
 #define TT_MS_LANGID_MAORI_NEW_ZEALAND                 0x0481
 
 #if 0  /* not deemed useful for fonts */
-#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE            0x04ff
+#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE            0x04FF
 #endif
 
 
diff --git a/include/tttables.h b/include/tttables.h
index bb49dc0..1568f40 100644
--- a/include/tttables.h
+++ b/include/tttables.h
@@ -5,7 +5,7 @@
 /*    Basic SFNT/TrueType tables definitions and interface                 */
 /*    (specification only).                                                */
 /*                                                                         */
-/*  Copyright 1996-2005, 2008-2013 by                                      */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -48,6 +48,25 @@
   /*    This section contains the definition of TrueType-specific tables   */
   /*    as well as some routines used to access and process them.          */
   /*                                                                       */
+  /* <Order>                                                               */
+  /*    TT_Header                                                          */
+  /*    TT_HoriHeader                                                      */
+  /*    TT_VertHeader                                                      */
+  /*    TT_OS2                                                             */
+  /*    TT_Postscript                                                      */
+  /*    TT_PCLT                                                            */
+  /*    TT_MaxProfile                                                      */
+  /*                                                                       */
+  /*    FT_Sfnt_Tag                                                        */
+  /*    FT_Get_Sfnt_Table                                                  */
+  /*    FT_Load_Sfnt_Table                                                 */
+  /*    FT_Sfnt_Table_Info                                                 */
+  /*                                                                       */
+  /*    FT_Get_CMap_Language_ID                                            */
+  /*    FT_Get_CMap_Format                                                 */
+  /*                                                                       */
+  /*    FT_PARAM_TAG_UNPATENTED_HINTING                                    */
+  /*                                                                       */
   /*************************************************************************/
 
 
@@ -352,7 +371,7 @@
     FT_Short   xAvgCharWidth;
     FT_UShort  usWeightClass;
     FT_UShort  usWidthClass;
-    FT_Short   fsType;
+    FT_UShort  fsType;
     FT_Short   ySubscriptXSize;
     FT_Short   ySubscriptYSize;
     FT_Short   ySubscriptXOffset;
@@ -559,21 +578,44 @@
   /*    An enumeration used to specify the index of an SFNT table.         */
   /*    Used in the @FT_Get_Sfnt_Table API function.                       */
   /*                                                                       */
+  /* <Values>                                                              */
+  /*    FT_SFNT_HEAD :: To access the font's @TT_Header structure.         */
+  /*                                                                       */
+  /*    FT_SFNT_MAXP :: To access the font's @TT_MaxProfile structure.     */
+  /*                                                                       */
+  /*    FT_SFNT_OS2  :: To access the font's @TT_OS2 structure.            */
+  /*                                                                       */
+  /*    FT_SFNT_HHEA :: To access the font's @TT_HoriHeader structure.     */
+  /*                                                                       */
+  /*    FT_SFNT_VHEA :: To access the font's @TT_VertHeader struture.      */
+  /*                                                                       */
+  /*    FT_SFNT_POST :: To access the font's @TT_Postscript structure.     */
+  /*                                                                       */
+  /*    FT_SFNT_PCLT :: To access the font's @TT_PCLT structure.           */
+  /*                                                                       */
   typedef enum  FT_Sfnt_Tag_
   {
-    ft_sfnt_head = 0,    /* TT_Header     */
-    ft_sfnt_maxp = 1,    /* TT_MaxProfile */
-    ft_sfnt_os2  = 2,    /* TT_OS2        */
-    ft_sfnt_hhea = 3,    /* TT_HoriHeader */
-    ft_sfnt_vhea = 4,    /* TT_VertHeader */
-    ft_sfnt_post = 5,    /* TT_Postscript */
-    ft_sfnt_pclt = 6,    /* TT_PCLT       */
+    FT_SFNT_HEAD,
+    FT_SFNT_MAXP,
+    FT_SFNT_OS2,
+    FT_SFNT_HHEA,
+    FT_SFNT_VHEA,
+    FT_SFNT_POST,
+    FT_SFNT_PCLT,
 
-    sfnt_max   /* internal end mark */
+    FT_SFNT_MAX
 
   } FT_Sfnt_Tag;
 
-  /* */
+  /* these constants are deprecated; use the corresponding `FT_Sfnt_Tag' */
+  /* values instead                                                      */
+#define ft_sfnt_head  FT_SFNT_HEAD
+#define ft_sfnt_maxp  FT_SFNT_MAXP
+#define ft_sfnt_os2   FT_SFNT_OS2
+#define ft_sfnt_hhea  FT_SFNT_HHEA
+#define ft_sfnt_vhea  FT_SFNT_VHEA
+#define ft_sfnt_post  FT_SFNT_POST
+#define ft_sfnt_pclt  FT_SFNT_PCLT
 
 
   /*************************************************************************/
@@ -611,7 +653,7 @@
   /*                                                                       */
   /*                                                                       */
   /*      vert_header =                                                    */
-  /*        (TT_VertHeader*)FT_Get_Sfnt_Table( face, ft_sfnt_vhea );       */
+  /*        (TT_VertHeader*)FT_Get_Sfnt_Table( face, FT_SFNT_VHEA );       */
   /*    }                                                                  */
   /*                                                                       */
   FT_EXPORT( void* )
diff --git a/include/tttags.h b/include/tttags.h
index d59aa19..3836c7b 100644
--- a/include/tttags.h
+++ b/include/tttags.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Tags for TrueType and OpenType tables (specification only).          */
 /*                                                                         */
-/*  Copyright 1996-2001, 2004, 2005, 2007, 2008, 2013 by                   */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/ttunpat.h b/include/ttunpat.h
index a016275..8ea5568 100644
--- a/include/ttunpat.h
+++ b/include/ttunpat.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Definitions for the unpatented TrueType hinting system               */
 /*                                                                         */
-/*  Copyright 2003, 2006 by                                                */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  Written by Graham Asher <graham.asher@btinternet.com>                  */
@@ -48,7 +48,8 @@
   */
 #define FT_PARAM_TAG_UNPATENTED_HINTING  FT_MAKE_TAG( 'u', 'n', 'p', 'a' )
 
- /* */
+  /* */
+
 
 FT_END_HEADER
 
diff --git a/src/autofit/afangles.c b/src/autofit/afangles.c
index b44a5ba..1b1eb31 100644
--- a/src/autofit/afangles.c
+++ b/src/autofit/afangles.c
@@ -5,7 +5,7 @@
 /*    Routines used to compute vector angles with limited accuracy         */
 /*    and very high speed.  It also contains sorting routines (body).      */
 /*                                                                         */
-/*  Copyright 2003-2006, 2011-2012 by                                      */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -20,66 +20,6 @@
 #include "aftypes.h"
 
 
-#if 0
-
-  FT_LOCAL_DEF( FT_Int )
-  af_corner_is_flat( FT_Pos  x_in,
-                     FT_Pos  y_in,
-                     FT_Pos  x_out,
-                     FT_Pos  y_out )
-  {
-    FT_Pos  ax = x_in;
-    FT_Pos  ay = y_in;
-
-    FT_Pos  d_in, d_out, d_corner;
-
-
-    if ( ax < 0 )
-      ax = -ax;
-    if ( ay < 0 )
-      ay = -ay;
-    d_in = ax + ay;
-
-    ax = x_out;
-    if ( ax < 0 )
-      ax = -ax;
-    ay = y_out;
-    if ( ay < 0 )
-      ay = -ay;
-    d_out = ax + ay;
-
-    ax = x_out + x_in;
-    if ( ax < 0 )
-      ax = -ax;
-    ay = y_out + y_in;
-    if ( ay < 0 )
-      ay = -ay;
-    d_corner = ax + ay;
-
-    return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
-  }
-
-
-  FT_LOCAL_DEF( FT_Int )
-  af_corner_orientation( FT_Pos  x_in,
-                         FT_Pos  y_in,
-                         FT_Pos  x_out,
-                         FT_Pos  y_out )
-  {
-    FT_Pos  delta;
-
-
-    delta = x_in * y_out - y_in * x_out;
-
-    if ( delta == 0 )
-      return 0;
-    else
-      return 1 - 2 * ( delta < 0 );
-  }
-
-#endif /* 0 */
-
-
   /*
    *  We are not using `af_angle_atan' anymore, but we keep the source
    *  code below just in case...
@@ -319,7 +259,7 @@
           sum         += table[j].org;
           table[j].org = 0;
         }
-        table[cur_idx].org = sum / j;
+        table[cur_idx].org = sum / (FT_Pos)j;
 
         if ( i < *count - 1 )
         {
diff --git a/src/autofit/afblue.c b/src/autofit/afblue.c
index f3526bf..e2b2451 100644
--- a/src/autofit/afblue.c
+++ b/src/autofit/afblue.c
@@ -7,7 +7,7 @@
 /*                                                                         */
 /*    Auto-fitter data for blue strings (body).                            */
 /*                                                                         */
-/*  Copyright 2013 by                                                      */
+/*  Copyright 2013-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -26,6 +26,10 @@
   af_blue_strings[] =
   {
     /* */
+    '\xD8', '\xA7', '\xD8', '\xA5', '\xD9', '\x84', '\xD9', '\x83', '\xD8', '\xB7', '\xD8', '\xB8',  /* ا إ ل ك ط ظ */
+    '\0',
+    '\xD8', '\xAA', '\xD8', '\xAB', '\xD8', '\xB7', '\xD8', '\xB8', '\xD9', '\x83',  /* ت ث ط ظ ك */
+    '\0',
     '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\x9F', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD',  /* БВЕПЗОСЭ */
     '\0',
     '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\xA8', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD',  /* БВЕШЗОСЭ */
@@ -67,6 +71,24 @@
     'x', 'z', 'r', 'o', 'e', 's', 'c',  /* xzroesc */
     '\0',
     'p', 'q', 'g', 'j', 'y',  /* pqgjy */
+    '\0',
+    '\xE0', '\xB0', '\x87', '\xE0', '\xB0', '\x8C', '\xE0', '\xB0', '\x99', '\xE0', '\xB0', '\x9E', '\xE0', '\xB0', '\xA3', '\xE0', '\xB0', '\xB1', '\xE0', '\xB1', '\xAF',  /* ఇ ఌ ఙ ఞ ణ ఱ ౯ */
+    '\0',
+    '\xE0', '\xB0', '\x85', '\xE0', '\xB0', '\x95', '\xE0', '\xB0', '\x9A', '\xE0', '\xB0', '\xB0', '\xE0', '\xB0', '\xBD', '\xE0', '\xB1', '\xA8', '\xE0', '\xB1', '\xAC',  /* అ క చ ర ఽ ౨ ౬ */
+    '\0',
+    '\xE0', '\xB8', '\x9A', '\xE0', '\xB9', '\x80', '\xE0', '\xB9', '\x81', '\xE0', '\xB8', '\xAD', '\xE0', '\xB8', '\x81', '\xE0', '\xB8', '\xB2',  /* บ เ แ อ ก า */
+    '\0',
+    '\xE0', '\xB8', '\x9A', '\xE0', '\xB8', '\x9B', '\xE0', '\xB8', '\xA9', '\xE0', '\xB8', '\xAF', '\xE0', '\xB8', '\xAD', '\xE0', '\xB8', '\xA2', '\xE0', '\xB8', '\xAE',  /* บ ป ษ ฯ อ ย ฮ */
+    '\0',
+    '\xE0', '\xB8', '\x9B', '\xE0', '\xB8', '\x9D', '\xE0', '\xB8', '\x9F',  /* ป ฝ ฟ */
+    '\0',
+    '\xE0', '\xB9', '\x82', '\xE0', '\xB9', '\x83', '\xE0', '\xB9', '\x84',  /* โ ใ ไ */
+    '\0',
+    '\xE0', '\xB8', '\x8E', '\xE0', '\xB8', '\x8F', '\xE0', '\xB8', '\xA4', '\xE0', '\xB8', '\xA6',  /* ฎ ฏ ฤ ฦ */
+    '\0',
+    '\xE0', '\xB8', '\x8D', '\xE0', '\xB8', '\x90',  /* ญ ฐ */
+    '\0',
+    '\xE0', '\xB9', '\x90', '\xE0', '\xB9', '\x91', '\xE0', '\xB9', '\x93',  /* ๐ ๑ ๓ */
 #ifdef AF_CONFIG_OPTION_CJK
     '\0',
     '\xE4', '\xBB', '\x96', '\xE4', '\xBB', '\xAC', '\xE4', '\xBD', '\xA0', '\xE4', '\xBE', '\x86', '\xE5', '\x80', '\x91', '\xE5', '\x88', '\xB0', '\xE5', '\x92', '\x8C', '\xE5', '\x9C', '\xB0',  /* 他们你來們到和地 */
@@ -117,6 +139,9 @@
   af_blue_stringsets[] =
   {
     /* */
+    { AF_BLUE_STRING_ARABIC_TOP,   AF_BLUE_PROPERTY_LATIN_TOP },
+    { AF_BLUE_STRING_ARABIC_JOIN,  0                          },
+    { AF_BLUE_STRING_MAX,          0                          },
     { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        },
     { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM,  0                                 },
     { AF_BLUE_STRING_CYRILLIC_SMALL,           AF_BLUE_PROPERTY_LATIN_TOP      |
@@ -153,6 +178,18 @@
     { AF_BLUE_STRING_LATIN_SMALL,           0                                 },
     { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0                                 },
     { AF_BLUE_STRING_MAX,                   0                                 },
+    { AF_BLUE_STRING_TELUGU_TOP,    AF_BLUE_PROPERTY_LATIN_TOP },
+    { AF_BLUE_STRING_TELUGU_BOTTOM, 0                          },
+    { AF_BLUE_STRING_MAX,           0                          },
+    { AF_BLUE_STRING_THAI_TOP,             AF_BLUE_PROPERTY_LATIN_TOP      |
+                                           AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
+    { AF_BLUE_STRING_THAI_BOTTOM,          0                                 },
+    { AF_BLUE_STRING_THAI_ASCENDER,        AF_BLUE_PROPERTY_LATIN_TOP        },
+    { AF_BLUE_STRING_THAI_LARGE_ASCENDER,  AF_BLUE_PROPERTY_LATIN_TOP        },
+    { AF_BLUE_STRING_THAI_DESCENDER,       0                                 },
+    { AF_BLUE_STRING_THAI_LARGE_DESCENDER, 0                                 },
+    { AF_BLUE_STRING_THAI_DIGIT_TOP,       0                                 },
+    { AF_BLUE_STRING_MAX,                  0                                 },
 #ifdef AF_CONFIG_OPTION_CJK
     { AF_BLUE_STRING_CJK_TOP,    AF_BLUE_PROPERTY_CJK_TOP     },
     { AF_BLUE_STRING_CJK_BOTTOM, 0                            },
diff --git a/src/autofit/afblue.cin b/src/autofit/afblue.cin
index c6762be..b303a4b 100644
--- a/src/autofit/afblue.cin
+++ b/src/autofit/afblue.cin
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter data for blue strings (body).                            */
 /*                                                                         */
-/*  Copyright 2013 by                                                      */
+/*  Copyright 2013-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afblue.dat b/src/autofit/afblue.dat
index 74a472d..fd5684e 100644
--- a/src/autofit/afblue.dat
+++ b/src/autofit/afblue.dat
@@ -2,7 +2,7 @@
 //
 //    Auto-fitter data for blue strings.
 //
-//  Copyright 2013, 2014 by
+//  Copyright 2013-2015 by
 //  David Turner, Robert Wilhelm, and Werner Lemberg.
 //
 //  This file is part of the FreeType project, and may only be used,
@@ -67,6 +67,11 @@
 
 AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN:
 
+  AF_BLUE_STRING_ARABIC_TOP
+    "ا إ ل ك ط ظ"
+  AF_BLUE_STRING_ARABIC_JOIN
+    "ت ث ط ظ ك"
+
   AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP
     "БВЕПЗОСЭ"
   AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM
@@ -119,6 +124,29 @@
   AF_BLUE_STRING_LATIN_SMALL_DESCENDER
     "pqgjy"
 
+  // we separate the letters with spaces to avoid ligatures;
+  // this is just for convenience to simplify reading
+  AF_BLUE_STRING_TELUGU_TOP
+    "ఇ ఌ ఙ ఞ ణ ఱ ౯"
+  AF_BLUE_STRING_TELUGU_BOTTOM
+    "అ క చ ర ఽ ౨ ౬"
+
+  AF_BLUE_STRING_THAI_TOP
+    "บ เ แ อ ก า"
+  AF_BLUE_STRING_THAI_BOTTOM
+    "บ ป ษ ฯ อ ย ฮ"
+  AF_BLUE_STRING_THAI_ASCENDER
+    "ป ฝ ฟ"
+  AF_BLUE_STRING_THAI_LARGE_ASCENDER
+    "โ ใ ไ"
+  AF_BLUE_STRING_THAI_DESCENDER
+    "ฎ ฏ ฤ ฦ"
+  AF_BLUE_STRING_THAI_LARGE_DESCENDER
+    "ญ ฐ"
+  AF_BLUE_STRING_THAI_DIGIT_TOP
+    "๐ ๑ ๓"
+
+
 #ifdef AF_CONFIG_OPTION_CJK
 
   AF_BLUE_STRING_CJK_TOP
@@ -260,6 +288,11 @@
 
 AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN:
 
+  AF_BLUE_STRINGSET_ARAB
+    { AF_BLUE_STRING_ARABIC_TOP,   AF_BLUE_PROPERTY_LATIN_TOP }
+    { AF_BLUE_STRING_ARABIC_JOIN,  0                          }
+    { AF_BLUE_STRING_MAX,          0                          }
+
   AF_BLUE_STRINGSET_CYRL
     { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        }
     { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM,  0                                 }
@@ -306,6 +339,23 @@
     { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0                                 }
     { AF_BLUE_STRING_MAX,                   0                                 }
 
+  AF_BLUE_STRINGSET_TELU
+    { AF_BLUE_STRING_TELUGU_TOP,    AF_BLUE_PROPERTY_LATIN_TOP }
+    { AF_BLUE_STRING_TELUGU_BOTTOM, 0                          }
+    { AF_BLUE_STRING_MAX,           0                          }
+
+  AF_BLUE_STRINGSET_THAI
+    { AF_BLUE_STRING_THAI_TOP,             AF_BLUE_PROPERTY_LATIN_TOP      |
+                                           AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
+    { AF_BLUE_STRING_THAI_BOTTOM,          0                                 }
+    { AF_BLUE_STRING_THAI_ASCENDER,        AF_BLUE_PROPERTY_LATIN_TOP        }
+    { AF_BLUE_STRING_THAI_LARGE_ASCENDER,  AF_BLUE_PROPERTY_LATIN_TOP        }
+    { AF_BLUE_STRING_THAI_DESCENDER,       0                                 }
+    { AF_BLUE_STRING_THAI_LARGE_DESCENDER, 0                                 }
+    { AF_BLUE_STRING_THAI_DIGIT_TOP,       0                                 }
+    { AF_BLUE_STRING_MAX,                  0                                 }
+
+
 #ifdef AF_CONFIG_OPTION_CJK
 
   AF_BLUE_STRINGSET_HANI
diff --git a/src/autofit/afblue.h b/src/autofit/afblue.h
index d239e8e..94e33a9 100644
--- a/src/autofit/afblue.h
+++ b/src/autofit/afblue.h
@@ -7,7 +7,7 @@
 /*                                                                         */
 /*    Auto-fitter data for blue strings (specification).                   */
 /*                                                                         */
-/*  Copyright 2013, 2014 by                                                */
+/*  Copyright 2013-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -74,28 +74,39 @@
 
   typedef enum  AF_Blue_String_
   {
-    AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 0,
-    AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 17,
-    AF_BLUE_STRING_CYRILLIC_SMALL = 34,
-    AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 51,
-    AF_BLUE_STRING_DEVANAGARI_BASE = 58,
-    AF_BLUE_STRING_DEVANAGARI_TOP = 83,
-    AF_BLUE_STRING_DEVANAGARI_HEAD = 108,
-    AF_BLUE_STRING_DEVANAGARI_BOTTOM = 133,
-    AF_BLUE_STRING_GREEK_CAPITAL_TOP = 140,
-    AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 155,
-    AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 168,
-    AF_BLUE_STRING_GREEK_SMALL = 181,
-    AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 198,
-    AF_BLUE_STRING_HEBREW_TOP = 215,
-    AF_BLUE_STRING_HEBREW_BOTTOM = 232,
-    AF_BLUE_STRING_HEBREW_DESCENDER = 245,
-    AF_BLUE_STRING_LATIN_CAPITAL_TOP = 256,
-    AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 265,
-    AF_BLUE_STRING_LATIN_SMALL_F_TOP = 274,
-    AF_BLUE_STRING_LATIN_SMALL = 282,
-    AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 290,
-    af_blue_1_1 = 295,
+    AF_BLUE_STRING_ARABIC_TOP = 0,
+    AF_BLUE_STRING_ARABIC_JOIN = 13,
+    AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 24,
+    AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 41,
+    AF_BLUE_STRING_CYRILLIC_SMALL = 58,
+    AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 75,
+    AF_BLUE_STRING_DEVANAGARI_BASE = 82,
+    AF_BLUE_STRING_DEVANAGARI_TOP = 107,
+    AF_BLUE_STRING_DEVANAGARI_HEAD = 132,
+    AF_BLUE_STRING_DEVANAGARI_BOTTOM = 157,
+    AF_BLUE_STRING_GREEK_CAPITAL_TOP = 164,
+    AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 179,
+    AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 192,
+    AF_BLUE_STRING_GREEK_SMALL = 205,
+    AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 222,
+    AF_BLUE_STRING_HEBREW_TOP = 239,
+    AF_BLUE_STRING_HEBREW_BOTTOM = 256,
+    AF_BLUE_STRING_HEBREW_DESCENDER = 269,
+    AF_BLUE_STRING_LATIN_CAPITAL_TOP = 280,
+    AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 289,
+    AF_BLUE_STRING_LATIN_SMALL_F_TOP = 298,
+    AF_BLUE_STRING_LATIN_SMALL = 306,
+    AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 314,
+    AF_BLUE_STRING_TELUGU_TOP = 320,
+    AF_BLUE_STRING_TELUGU_BOTTOM = 342,
+    AF_BLUE_STRING_THAI_TOP = 364,
+    AF_BLUE_STRING_THAI_BOTTOM = 383,
+    AF_BLUE_STRING_THAI_ASCENDER = 405,
+    AF_BLUE_STRING_THAI_LARGE_ASCENDER = 415,
+    AF_BLUE_STRING_THAI_DESCENDER = 425,
+    AF_BLUE_STRING_THAI_LARGE_DESCENDER = 438,
+    AF_BLUE_STRING_THAI_DIGIT_TOP = 445,
+    af_blue_1_1 = 454,
 #ifdef AF_CONFIG_OPTION_CJK
     AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1,
     AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 153,
@@ -136,29 +147,32 @@
   /* Properties are specific to a writing system.  We assume that a given  */
   /* blue string can't be used in more than a single writing system, which */
   /* is a safe bet.                                                        */
-#define AF_BLUE_PROPERTY_LATIN_TOP       ( 1 << 0 )   /* must have value 1 */
-#define AF_BLUE_PROPERTY_LATIN_NEUTRAL   ( 1 << 1 )
-#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT  ( 1 << 2 )
-#define AF_BLUE_PROPERTY_LATIN_LONG      ( 1 << 3 )
+#define AF_BLUE_PROPERTY_LATIN_TOP       ( 1U << 0 )  /* must have value 1 */
+#define AF_BLUE_PROPERTY_LATIN_NEUTRAL   ( 1U << 1 )
+#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT  ( 1U << 2 )
+#define AF_BLUE_PROPERTY_LATIN_LONG      ( 1U << 3 )
 
-#define AF_BLUE_PROPERTY_CJK_TOP    ( 1 << 0 )        /* must have value 1 */
-#define AF_BLUE_PROPERTY_CJK_HORIZ  ( 1 << 1 )        /* must have value 2 */
+#define AF_BLUE_PROPERTY_CJK_TOP    ( 1U << 0 )       /* must have value 1 */
+#define AF_BLUE_PROPERTY_CJK_HORIZ  ( 1U << 1 )       /* must have value 2 */
 #define AF_BLUE_PROPERTY_CJK_RIGHT  AF_BLUE_PROPERTY_CJK_TOP
 
 
-#define AF_BLUE_STRINGSET_MAX_LEN  7
+#define AF_BLUE_STRINGSET_MAX_LEN  8
 
   /* The AF_Blue_Stringset enumeration values are offsets into the */
   /* `af_blue_stringsets' array.                                   */
 
   typedef enum  AF_Blue_Stringset_
   {
-    AF_BLUE_STRINGSET_CYRL = 0,
-    AF_BLUE_STRINGSET_DEVA = 6,
-    AF_BLUE_STRINGSET_GREK = 12,
-    AF_BLUE_STRINGSET_HEBR = 19,
-    AF_BLUE_STRINGSET_LATN = 23,
-    af_blue_2_1 = 30,
+    AF_BLUE_STRINGSET_ARAB = 0,
+    AF_BLUE_STRINGSET_CYRL = 3,
+    AF_BLUE_STRINGSET_DEVA = 9,
+    AF_BLUE_STRINGSET_GREK = 15,
+    AF_BLUE_STRINGSET_HEBR = 22,
+    AF_BLUE_STRINGSET_LATN = 26,
+    AF_BLUE_STRINGSET_TELU = 33,
+    AF_BLUE_STRINGSET_THAI = 36,
+    af_blue_2_1 = 44,
 #ifdef AF_CONFIG_OPTION_CJK
     AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0,
     af_blue_2_1_1 = af_blue_2_1 + 2,
diff --git a/src/autofit/afblue.hin b/src/autofit/afblue.hin
index 0b4b48d..ad43fe6 100644
--- a/src/autofit/afblue.hin
+++ b/src/autofit/afblue.hin
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter data for blue strings (specification).                   */
 /*                                                                         */
-/*  Copyright 2013, 2014 by                                                */
+/*  Copyright 2013-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -96,13 +96,13 @@
   /* Properties are specific to a writing system.  We assume that a given  */
   /* blue string can't be used in more than a single writing system, which */
   /* is a safe bet.                                                        */
-#define AF_BLUE_PROPERTY_LATIN_TOP       ( 1 << 0 )   /* must have value 1 */
-#define AF_BLUE_PROPERTY_LATIN_NEUTRAL   ( 1 << 1 )
-#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT  ( 1 << 2 )
-#define AF_BLUE_PROPERTY_LATIN_LONG      ( 1 << 3 )
+#define AF_BLUE_PROPERTY_LATIN_TOP       ( 1U << 0 )  /* must have value 1 */
+#define AF_BLUE_PROPERTY_LATIN_NEUTRAL   ( 1U << 1 )
+#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT  ( 1U << 2 )
+#define AF_BLUE_PROPERTY_LATIN_LONG      ( 1U << 3 )
 
-#define AF_BLUE_PROPERTY_CJK_TOP    ( 1 << 0 )        /* must have value 1 */
-#define AF_BLUE_PROPERTY_CJK_HORIZ  ( 1 << 1 )        /* must have value 2 */
+#define AF_BLUE_PROPERTY_CJK_TOP    ( 1U << 0 )       /* must have value 1 */
+#define AF_BLUE_PROPERTY_CJK_HORIZ  ( 1U << 1 )       /* must have value 2 */
 #define AF_BLUE_PROPERTY_CJK_RIGHT  AF_BLUE_PROPERTY_CJK_TOP
 
 
diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c
index ca7acca..905408b 100644
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines for CJK writing system (body).          */
 /*                                                                         */
-/*  Copyright 2006-2014 by                                                 */
+/*  Copyright 2006-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -260,8 +260,8 @@
     FT_Pos      fills[AF_BLUE_STRING_MAX_LEN];
     FT_Pos      flats[AF_BLUE_STRING_MAX_LEN];
 
-    FT_Int      num_fills;
-    FT_Int      num_flats;
+    FT_UInt     num_fills;
+    FT_UInt     num_flats;
 
     FT_Bool     fill;
 
@@ -720,8 +720,8 @@
     {
       AF_Point  pt   = seg->first;
       AF_Point  last = seg->last;
-      AF_Flags  f0   = (AF_Flags)( pt->flags & AF_FLAG_CONTROL );
-      AF_Flags  f1;
+      FT_UInt   f0   = pt->flags & AF_FLAG_CONTROL;
+      FT_UInt   f1;
 
 
       seg->flags &= ~AF_EDGE_ROUND;
@@ -729,7 +729,7 @@
       for ( ; pt != last; f0 = f1 )
       {
         pt = pt->next;
-        f1 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL );
+        f1 = pt->flags & AF_FLAG_CONTROL;
 
         if ( !f0 && !f1 )
           break;
@@ -765,10 +765,6 @@
     /* now compare each segment to the others */
     for ( seg1 = segments; seg1 < segment_limit; seg1++ )
     {
-      /* the fake segments are for metrics hinting only */
-      if ( seg1->first == seg1->last )
-        continue;
-
       if ( seg1->dir != major_dir )
         continue;
 
@@ -867,19 +863,19 @@
 
               if ( link == seg2 )
               {
-                seg->link  = 0;
+                seg->link  = NULL;
                 seg->serif = link1;
               }
               else if ( link == link2 )
               {
-                seg->link  = 0;
+                seg->link  = NULL;
                 seg->serif = seg1;
               }
             }
           }
           else
           {
-            seg1->link = link1->link = 0;
+            seg1->link = link1->link = NULL;
 
             break;
           }
@@ -896,7 +892,7 @@
         seg2->num_linked++;
         if ( seg2->link != seg1 )
         {
-          seg1->link = 0;
+          seg1->link = NULL;
 
           if ( seg2->score < dist_threshold || seg1->score < seg2->score * 4 )
             seg1->serif = seg2->link;
@@ -1028,10 +1024,11 @@
 
         edge->first    = seg;
         edge->last     = seg;
-        edge->fpos     = seg->pos;
-        edge->opos     = edge->pos = FT_MulFix( seg->pos, scale );
-        seg->edge_next = seg;
         edge->dir      = seg->dir;
+        edge->fpos     = seg->pos;
+        edge->opos     = FT_MulFix( seg->pos, scale );
+        edge->pos      = edge->opos;
+        seg->edge_next = seg;
       }
       else
       {
@@ -1162,7 +1159,7 @@
         /*      Example: the `c' in cour.pfa at size 13     */
 
         if ( edge->serif && edge->link )
-          edge->serif = 0;
+          edge->serif = NULL;
       }
     }
 
@@ -1193,7 +1190,7 @@
 
   /* Compute all edges which lie within blue zones. */
 
-  FT_LOCAL_DEF( void )
+  static void
   af_cjk_hints_compute_blue_edges( AF_GlyphHints  hints,
                                    AF_CJKMetrics  metrics,
                                    AF_Dimension   dim )
@@ -1304,7 +1301,7 @@
     /* compute flags depending on render mode, etc. */
     mode = metrics->root.scaler.render_mode;
 
-#ifdef AF_CONFIG_OPTION_USE_WARPER
+#if 0 /* AF_CONFIG_OPTION_USE_WARPER */
     if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )
       metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;
 #endif
@@ -1337,6 +1334,12 @@
 
     scaler_flags |= AF_SCALER_FLAG_NO_ADVANCE;
 
+#ifdef AF_CONFIG_OPTION_USE_WARPER
+    /* get (global) warper flag */
+    if ( !metrics->root.globals->module->warping )
+      scaler_flags |= AF_SCALER_FLAG_NO_WARPER;
+#endif
+
     hints->scaler_flags = scaler_flags;
     hints->other_flags  = other_flags;
 
@@ -1357,13 +1360,13 @@
 
   static FT_Pos
   af_cjk_snap_width( AF_Width  widths,
-                     FT_Int    count,
+                     FT_UInt   count,
                      FT_Pos    width )
   {
-    int     n;
-    FT_Pos  best      = 64 + 32 + 2;
-    FT_Pos  reference = width;
-    FT_Pos  scaled;
+    FT_UInt  n;
+    FT_Pos   best      = 64 + 32 + 2;
+    FT_Pos   reference = width;
+    FT_Pos   scaled;
 
 
     for ( n = 0; n < count; n++ )
@@ -1408,8 +1411,8 @@
   af_cjk_compute_stem_width( AF_GlyphHints  hints,
                              AF_Dimension   dim,
                              FT_Pos         width,
-                             AF_Edge_Flags  base_flags,
-                             AF_Edge_Flags  stem_flags )
+                             FT_UInt        base_flags,
+                             FT_UInt        stem_flags )
   {
     AF_CJKMetrics  metrics  = (AF_CJKMetrics)hints->metrics;
     AF_CJKAxis     axis     = &metrics->axis[dim];
@@ -1533,10 +1536,9 @@
   {
     FT_Pos  dist = stem_edge->opos - base_edge->opos;
 
-    FT_Pos  fitted_width = af_cjk_compute_stem_width(
-                             hints, dim, dist,
-                             (AF_Edge_Flags)base_edge->flags,
-                             (AF_Edge_Flags)stem_edge->flags );
+    FT_Pos  fitted_width = af_cjk_compute_stem_width( hints, dim, dist,
+                                                      base_edge->flags,
+                                                      stem_edge->flags );
 
 
     stem_edge->pos = base_edge->pos + fitted_width;
@@ -1614,8 +1616,8 @@
 
     org_len    = edge2->opos - edge->opos;
     cur_len    = af_cjk_compute_stem_width( hints, dim, org_len,
-                                            (AF_Edge_Flags)edge->flags,
-                                            (AF_Edge_Flags)edge2->flags );
+                                            edge->flags,
+                                            edge2->flags );
 
     org_center = ( edge->opos + edge2->opos ) / 2 + anchor;
     cur_pos1   = org_center - cur_len / 2;
@@ -1716,7 +1718,7 @@
     AF_Edge       edge_limit = edges + axis->num_edges;
     FT_PtrDist    n_edges;
     AF_Edge       edge;
-    AF_Edge       anchor   = 0;
+    AF_Edge       anchor   = NULL;
     FT_Pos        delta    = 0;
     FT_Int        skipped  = 0;
     FT_Bool       has_last_stem = FALSE;
@@ -2194,7 +2196,13 @@
       goto Exit;
 
     /* analyze glyph outline */
+#ifdef AF_CONFIG_OPTION_USE_WARPER
+    if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT &&
+           AF_HINTS_DO_WARP( hints )                                ) ||
+         AF_HINTS_DO_HORIZONTAL( hints )                              )
+#else
     if ( AF_HINTS_DO_HORIZONTAL( hints ) )
+#endif
     {
       error = af_cjk_hints_detect_features( hints, AF_DIMENSION_HORZ );
       if ( error )
@@ -2220,8 +2228,9 @@
       {
 
 #ifdef AF_CONFIG_OPTION_USE_WARPER
-        if ( dim == AF_DIMENSION_HORZ                                  &&
-             metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL )
+        if ( dim == AF_DIMENSION_HORZ                                 &&
+             metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT &&
+             AF_HINTS_DO_WARP( hints )                                )
         {
           AF_WarperRec  warper;
           FT_Fixed      scale;
@@ -2243,12 +2252,6 @@
       }
     }
 
-#if 0
-    af_glyph_hints_dump_points( hints );
-    af_glyph_hints_dump_segments( hints );
-    af_glyph_hints_dump_edges( hints );
-#endif
-
     af_glyph_hints_save( hints, outline );
 
   Exit:
diff --git a/src/autofit/afcjk.h b/src/autofit/afcjk.h
index 4dd4f39..bfd11f2 100644
--- a/src/autofit/afcjk.h
+++ b/src/autofit/afcjk.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines for CJK writing system (specification). */
 /*                                                                         */
-/*  Copyright 2006, 2007, 2011-2014 by                                     */
+/*  Copyright 2006-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -55,14 +55,10 @@
 #define AF_CJK_MAX_WIDTHS  16
 
 
-  enum
-  {
-    AF_CJK_BLUE_ACTIVE     = 1 << 0,  /* set if zone height is <= 3/4px */
-    AF_CJK_BLUE_TOP        = 1 << 1,  /* result of AF_CJK_IS_TOP_BLUE   */
-    AF_CJK_BLUE_ADJUSTMENT = 1 << 2,  /* used for scale adjustment      */
-                                      /* optimization                   */
-    AF_CJK_BLUE_FLAG_MAX
-  };
+#define AF_CJK_BLUE_ACTIVE      ( 1U << 0 ) /* zone height is <= 3/4px      */
+#define AF_CJK_BLUE_TOP         ( 1U << 1 ) /* result of AF_CJK_IS_TOP_BLUE */
+#define AF_CJK_BLUE_ADJUSTMENT  ( 1U << 2 ) /* used for scale adjustment    */
+                                            /* optimization                 */
 
 
   typedef struct  AF_CJKBlueRec_
diff --git a/src/autofit/afcover.h b/src/autofit/afcover.h
index d5ac969..520e8a4 100644
--- a/src/autofit/afcover.h
+++ b/src/autofit/afcover.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter coverages (specification only).                          */
 /*                                                                         */
-/*  Copyright 2013, 2014 by                                                */
+/*  Copyright 2013-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afdummy.c b/src/autofit/afdummy.c
index f8702a1..03ca25f 100644
--- a/src/autofit/afdummy.c
+++ b/src/autofit/afdummy.c
@@ -5,7 +5,7 @@
 /*    Auto-fitter dummy routines to be used if no hinting should be        */
 /*    performed (body).                                                    */
 /*                                                                         */
-/*  Copyright 2003-2005, 2011, 2013 by                                     */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afdummy.h b/src/autofit/afdummy.h
index ad1b0d3..b4fdc78 100644
--- a/src/autofit/afdummy.h
+++ b/src/autofit/afdummy.h
@@ -5,7 +5,7 @@
 /*    Auto-fitter dummy routines to be used if no hinting should be        */
 /*    performed (specification).                                           */
 /*                                                                         */
-/*  Copyright 2003-2005, 2011, 2013 by                                     */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/aferrors.h b/src/autofit/aferrors.h
index 50e1a22..7b416e4 100644
--- a/src/autofit/aferrors.h
+++ b/src/autofit/aferrors.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Autofitter error codes (specification only).                         */
 /*                                                                         */
-/*  Copyright 2005, 2012 by                                                */
+/*  Copyright 2005-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c
index a54c20c..64b9293 100644
--- a/src/autofit/afglobal.c
+++ b/src/autofit/afglobal.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter routines to compute global hinting values (body).        */
 /*                                                                         */
-/*  Copyright 2003-2014 by                                                 */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -314,8 +314,9 @@
 
     memory = face->memory;
 
-    if ( FT_ALLOC( globals, sizeof ( *globals ) +
-                            face->num_glyphs * sizeof ( FT_Byte ) ) )
+    if ( FT_ALLOC( globals,
+                   sizeof ( *globals ) +
+                     (FT_ULong)face->num_glyphs * sizeof ( FT_Byte ) ) )
       goto Exit;
 
     globals->face         = face;
diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h
index 38d8d69..9bbb687 100644
--- a/src/autofit/afglobal.h
+++ b/src/autofit/afglobal.h
@@ -5,7 +5,7 @@
 /*    Auto-fitter routines to compute global hinting values                */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2003-2005, 2007, 2009, 2011-2014 by                          */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c
index 88a97d4..37482eb 100644
--- a/src/autofit/afhints.c
+++ b/src/autofit/afhints.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines (body).                                 */
 /*                                                                         */
-/*  Copyright 2003-2007, 2009-2014 by                                      */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -43,7 +43,15 @@
     AF_Segment  segment = NULL;
 
 
-    if ( axis->num_segments >= axis->max_segments )
+    if ( axis->num_segments < AF_SEGMENTS_EMBEDDED )
+    {
+      if ( axis->segments == NULL )
+      {
+        axis->segments     = axis->embedded.segments;
+        axis->max_segments = AF_SEGMENTS_EMBEDDED;
+      }
+    }
+    else if ( axis->num_segments >= axis->max_segments )
     {
       FT_Int  old_max = axis->max_segments;
       FT_Int  new_max = old_max;
@@ -60,8 +68,18 @@
       if ( new_max < old_max || new_max > big_max )
         new_max = big_max;
 
-      if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )
-        goto Exit;
+      if ( axis->segments == axis->embedded.segments )
+      {
+        if ( FT_NEW_ARRAY( axis->segments, new_max ) )
+          goto Exit;
+        ft_memcpy( axis->segments, axis->embedded.segments,
+                   sizeof ( axis->embedded.segments ) );
+      }
+      else
+      {
+        if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )
+          goto Exit;
+      }
 
       axis->max_segments = new_max;
     }
@@ -74,7 +92,8 @@
   }
 
 
-  /* Get new edge for given axis, direction, and position. */
+  /* Get new edge for given axis, direction, and position, */
+  /* without initializing the edge itself.                 */
 
   FT_LOCAL( FT_Error )
   af_axis_hints_new_edge( AF_AxisHints  axis,
@@ -88,7 +107,15 @@
     AF_Edge   edges;
 
 
-    if ( axis->num_edges >= axis->max_edges )
+    if ( axis->num_edges < AF_EDGES_EMBEDDED )
+    {
+      if ( axis->edges == NULL )
+      {
+        axis->edges     = axis->embedded.edges;
+        axis->max_edges = AF_EDGES_EMBEDDED;
+      }
+    }
+    else if ( axis->num_edges >= axis->max_edges )
     {
       FT_Int  old_max = axis->max_edges;
       FT_Int  new_max = old_max;
@@ -105,8 +132,18 @@
       if ( new_max < old_max || new_max > big_max )
         new_max = big_max;
 
-      if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )
-        goto Exit;
+      if ( axis->edges == axis->embedded.edges )
+      {
+        if ( FT_NEW_ARRAY( axis->edges, new_max ) )
+          goto Exit;
+        ft_memcpy( axis->edges, axis->embedded.edges,
+                   sizeof ( axis->embedded.edges ) );
+      }
+      else
+      {
+        if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )
+          goto Exit;
+      }
 
       axis->max_edges = new_max;
     }
@@ -130,10 +167,6 @@
 
     axis->num_edges++;
 
-    FT_ZERO( edge );
-    edge->fpos = (FT_Short)fpos;
-    edge->dir  = (FT_Char)dir;
-
   Exit:
     *anedge = edge;
     return error;
@@ -183,7 +216,7 @@
   }
 
 
-#define AF_INDEX_NUM( ptr, base )  ( (ptr) ? ( (ptr) - (base) ) : -1 )
+#define AF_INDEX_NUM( ptr, base )  (int)( (ptr) ? ( (ptr) - (base) ) : -1 )
 
 
 #ifdef __cplusplus
@@ -198,26 +231,25 @@
     AF_Point  point;
 
 
-    AF_DUMP(( "Table of points:\n"
-              "  [ index |  xorg |  yorg | xscale | yscale"
-              " |  xfit |  yfit |  flags ]\n" ));
+    AF_DUMP(( "Table of points:\n" ));
+
+    if ( hints->num_points )
+      AF_DUMP(( "  [ index |  xorg |  yorg | xscale | yscale"
+                " |  xfit |  yfit |  flags ]\n" ));
+    else
+      AF_DUMP(( "  (none)\n" ));
 
     for ( point = points; point < limit; point++ )
       AF_DUMP(( "  [ %5d | %5d | %5d | %6.2f | %6.2f"
-                " | %5.2f | %5.2f | %c%c%c%c%c%c ]\n",
-                point - points,
+                " | %5.2f | %5.2f | %c ]\n",
+                AF_INDEX_NUM( point, points ),
                 point->fx,
                 point->fy,
                 point->ox / 64.0,
                 point->oy / 64.0,
                 point->x / 64.0,
                 point->y / 64.0,
-                ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ',
-                ( point->flags & AF_FLAG_INFLECTION )         ? 'i' : ' ',
-                ( point->flags & AF_FLAG_EXTREMA_X )          ? '<' : ' ',
-                ( point->flags & AF_FLAG_EXTREMA_Y )          ? 'v' : ' ',
-                ( point->flags & AF_FLAG_ROUND_X )            ? '(' : ' ',
-                ( point->flags & AF_FLAG_ROUND_Y )            ? 'u' : ' '));
+                ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' '));
     AF_DUMP(( "\n" ));
   }
 #ifdef __cplusplus
@@ -226,7 +258,7 @@
 
 
   static const char*
-  af_edge_flags_to_string( AF_Edge_Flags  flags )
+  af_edge_flags_to_string( FT_UInt  flags )
   {
     static char  temp[32];
     int          pos = 0;
@@ -289,7 +321,7 @@
         AF_DUMP(( "  [ %5d | %5.2g | %5s | %4d"
                   " | %4d | %4d | %5d | %4d"
                   " | %6d | %5d | %11s ]\n",
-                  seg - segments,
+                  AF_INDEX_NUM( seg, segments ),
                   dimension == AF_DIMENSION_HORZ
                                ? (int)seg->first->ox / 64.0
                                : (int)seg->first->oy / 64.0,
@@ -301,7 +333,7 @@
                   AF_INDEX_NUM( seg->edge, edges ),
                   seg->height,
                   seg->height - ( seg->max_coord - seg->min_coord ),
-                  af_edge_flags_to_string( (AF_Edge_Flags)seg->flags ) ));
+                  af_edge_flags_to_string( seg->flags ) ));
       AF_DUMP(( "\n" ));
     }
   }
@@ -420,7 +452,7 @@
       for ( edge = edges; edge < limit; edge++ )
         AF_DUMP(( "  [ %5d | %5.2g | %5s | %4d"
                   " | %5d |   %c  | %5.2f | %5.2f | %11s ]\n",
-                  edge - edges,
+                  AF_INDEX_NUM( edge, edges ),
                   (int)edge->opos / 64.0,
                   af_dir_str( (AF_Direction)edge->dir ),
                   AF_INDEX_NUM( edge->link, edges ),
@@ -428,7 +460,7 @@
                   edge->blue_edge ? 'y' : 'n',
                   edge->opos / 64.0,
                   edge->pos / 64.0,
-                  af_edge_flags_to_string( (AF_Edge_Flags)edge->flags ) ));
+                  af_edge_flags_to_string( edge->flags ) ));
       AF_DUMP(( "\n" ));
     }
   }
@@ -477,15 +509,15 @@
       else
       {
         dir = AF_DIR_DOWN;
-        ll  = dy;
+        ll  = -dy;
         ss  = dx;
       }
     }
 
-    /* return no direction if arm lengths differ too much            */
+    /* return no direction if arm lengths do not differ enough       */
     /* (value 14 is heuristic, corresponding to approx. 4.1 degrees) */
-    ss *= 14;
-    if ( FT_ABS( ll ) <= FT_ABS( ss ) )
+    /* the long arm is never negative                                */
+    if ( ll <= 14 * FT_ABS( ss ) )
       dir = AF_DIR_NONE;
 
     return dir;
@@ -496,7 +528,8 @@
   af_glyph_hints_init( AF_GlyphHints  hints,
                        FT_Memory      memory )
   {
-    FT_ZERO( hints );
+    /* no need to initialize the embedded items */
+    FT_MEM_ZERO( hints, sizeof ( *hints ) - sizeof ( hints->embedded ) );
     hints->memory = memory;
   }
 
@@ -504,13 +537,15 @@
   FT_LOCAL_DEF( void )
   af_glyph_hints_done( AF_GlyphHints  hints )
   {
-    FT_Memory  memory = hints->memory;
+    FT_Memory  memory;
     int        dim;
 
 
     if ( !( hints && hints->memory ) )
       return;
 
+    memory = hints->memory;
+
     /*
      *  note that we don't need to free the segment and edge
      *  buffers since they are really within the hints->points array
@@ -522,20 +557,24 @@
 
       axis->num_segments = 0;
       axis->max_segments = 0;
-      FT_FREE( axis->segments );
+      if ( axis->segments != axis->embedded.segments )
+        FT_FREE( axis->segments );
 
       axis->num_edges = 0;
       axis->max_edges = 0;
-      FT_FREE( axis->edges );
+      if ( axis->edges != axis->embedded.edges )
+        FT_FREE( axis->edges );
     }
 
-    FT_FREE( hints->contours );
+    if ( hints->contours != hints->embedded.contours )
+      FT_FREE( hints->contours );
     hints->max_contours = 0;
     hints->num_contours = 0;
 
-    FT_FREE( hints->points );
-    hints->num_points = 0;
+    if ( hints->points != hints->embedded.points )
+      FT_FREE( hints->points );
     hints->max_points = 0;
+    hints->num_points = 0;
 
     hints->memory = NULL;
   }
@@ -579,15 +618,27 @@
 
     /* first of all, reallocate the contours array if necessary */
     new_max = (FT_UInt)outline->n_contours;
-    old_max = hints->max_contours;
-    if ( new_max > old_max )
+    old_max = (FT_UInt)hints->max_contours;
+
+    if ( new_max <= AF_CONTOURS_EMBEDDED )
     {
-      new_max = ( new_max + 3 ) & ~3; /* round up to a multiple of 4 */
+      if ( hints->contours == NULL )
+      {
+        hints->contours     = hints->embedded.contours;
+        hints->max_contours = AF_CONTOURS_EMBEDDED;
+      }
+    }
+    else if ( new_max > old_max )
+    {
+      if ( hints->contours == hints->embedded.contours )
+        hints->contours = NULL;
+
+      new_max = ( new_max + 3 ) & ~3U; /* round up to a multiple of 4 */
 
       if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
         goto Exit;
 
-      hints->max_contours = new_max;
+      hints->max_contours = (FT_Int)new_max;
     }
 
     /*
@@ -596,15 +647,27 @@
      *  hint metrics appropriately
      */
     new_max = (FT_UInt)( outline->n_points + 2 );
-    old_max = hints->max_points;
-    if ( new_max > old_max )
+    old_max = (FT_UInt)hints->max_points;
+
+    if ( new_max <= AF_POINTS_EMBEDDED )
     {
-      new_max = ( new_max + 2 + 7 ) & ~7; /* round up to a multiple of 8 */
+      if ( hints->points == NULL )
+      {
+        hints->points     = hints->embedded.points;
+        hints->max_points = AF_POINTS_EMBEDDED;
+      }
+    }
+    else if ( new_max > old_max )
+    {
+      if ( hints->points == hints->embedded.points )
+        hints->points = NULL;
+
+      new_max = ( new_max + 2 + 7 ) & ~7U; /* round up to a multiple of 8 */
 
       if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) )
         goto Exit;
 
-      hints->max_points = new_max;
+      hints->max_points = (FT_Int)new_max;
     }
 
     hints->num_points   = outline->n_points;
@@ -729,8 +792,6 @@
 
           FT_Pos  out_x, out_y;
 
-          FT_Bool  is_first;
-
 
           /* since the first point of a contour could be part of a */
           /* series of near points, go backwards to find the first */
@@ -781,17 +842,13 @@
           out_x = 0;
           out_y = 0;
 
-          is_first = 1;
-
-          for ( point = first;
-                point != first || is_first;
-                point = point->next )
+          next = first;
+          do
           {
             AF_Direction  out_dir;
 
 
-            is_first = 0;
-
+            point = next;
             next = point->next;
 
             out_x += next->fx - point->fx;
@@ -823,7 +880,8 @@
 
             out_x = 0;
             out_y = 0;
-          }
+
+          } while ( next != first );
         }
 
         /*
@@ -1053,7 +1111,7 @@
     AF_AxisHints  axis        = &hints->axis[dim];
     AF_Edge       edges       = axis->edges;
     AF_Edge       edge_limit  = edges + axis->num_edges;
-    AF_Flags      touch_flag;
+    FT_UInt       touch_flag;
 
 
     if ( dim == AF_DIMENSION_HORZ )
@@ -1079,8 +1137,7 @@
         /* if this point is candidate to weak interpolation, we       */
         /* interpolate it after all strong points have been processed */
 
-        if (  ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) &&
-             !( point->flags & AF_FLAG_INFLECTION )         )
+        if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) )
           continue;
 
         if ( dim == AF_DIMENSION_VERT )
@@ -1235,33 +1292,27 @@
                  AF_Point  ref2 )
   {
     AF_Point  p;
-    FT_Pos    u;
-    FT_Pos    v1 = ref1->v;
-    FT_Pos    v2 = ref2->v;
-    FT_Pos    d1 = ref1->u - v1;
-    FT_Pos    d2 = ref2->u - v2;
+    FT_Pos    u, v1, v2, u1, u2, d1, d2;
 
 
     if ( p1 > p2 )
       return;
 
-    if ( v1 == v2 )
+    if ( ref1->v > ref2->v )
     {
-      for ( p = p1; p <= p2; p++ )
-      {
-        u = p->v;
-
-        if ( u <= v1 )
-          u += d1;
-        else
-          u += d2;
-
-        p->u = u;
-      }
-      return;
+      p    = ref1;
+      ref1 = ref2;
+      ref2 = p;
     }
 
-    if ( v1 < v2 )
+    v1 = ref1->v;
+    v2 = ref2->v;
+    u1 = ref1->u;
+    u2 = ref2->u;
+    d1 = u1 - v1;
+    d2 = u2 - v2;
+
+    if ( u1 == u2 || v1 == v2 )
     {
       for ( p = p1; p <= p2; p++ )
       {
@@ -1272,23 +1323,26 @@
         else if ( u >= v2 )
           u += d2;
         else
-          u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
+          u = u1;
 
         p->u = u;
       }
     }
     else
     {
+      FT_Fixed  scale = FT_DivFix( u2 - u1, v2 - v1 );
+
+
       for ( p = p1; p <= p2; p++ )
       {
         u = p->v;
 
-        if ( u <= v2 )
-          u += d2;
-        else if ( u >= v1 )
+        if ( u <= v1 )
           u += d1;
+        else if ( u >= v2 )
+          u += d2;
         else
-          u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
+          u = u1 + FT_MulFix( u - v1, scale );
 
         p->u = u;
       }
@@ -1307,7 +1361,7 @@
     AF_Point   point_limit   = points + hints->num_points;
     AF_Point*  contour       = hints->contours;
     AF_Point*  contour_limit = contour + hints->num_contours;
-    AF_Flags   touch_flag;
+    FT_UInt    touch_flag;
     AF_Point   point;
     AF_Point   end_point;
     AF_Point   first_point;
diff --git a/src/autofit/afhints.h b/src/autofit/afhints.h
index c0ebd0d..a64c7a4 100644
--- a/src/autofit/afhints.h
+++ b/src/autofit/afhints.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines (specification).                        */
 /*                                                                         */
-/*  Copyright 2003-2008, 2010-2012, 2014 by                                */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -72,13 +72,9 @@
    *    `af_{cjk,latin,...}_hints_compute_segments' are the functions to
    *    find segments in an outline.
    *
-   *    A segment is a series of consecutive points that are approximately
-   *    aligned along a coordinate axis.  The analysis to do so is specific
-   *    to a writing system.
-   *
-   *    A segment must have at least two points, except in the case of
-   *    `fake' segments that are generated to hint metrics appropriately,
-   *    and which consist of a single point.
+   *    A segment is a series of at least two consecutive points that are
+   *    approximately aligned along a coordinate axis.  The analysis to do
+   *    so is specific to a writing system.
    *
    *
    *  Edges
@@ -148,7 +144,7 @@
    *    Serifs are detected by `af_{cjk,latin,...}_hint_edges'.
    *
    *    In comparison to a stem, a serif (as handled by the auto-hinter
-   *    module which takes care of the `latin' writing system) has
+   *    module that takes care of the `latin' writing system) has
    *
    *      best segment_1 = segment_2 && best segment_2 != segment_1
    *
@@ -178,19 +174,19 @@
    *
    *  Strong Points
    *
-   *    Experience has shown that points which are not part of an edge need
-   *    to be interpolated linearly between their two closest edges, even if
-   *    these are not part of the contour of those particular points.
-   *    Typical candidates for this are
+   *    Experience has shown that points not part of an edge need to be
+   *    interpolated linearly between their two closest edges, even if these
+   *    are not part of the contour of those particular points.  Typical
+   *    candidates for this are
    *
    *    - angle points (i.e., points where the `in' and `out' direction
    *      differ greatly)
    *
    *    - inflection points (i.e., where the `in' and `out' angles are the
    *      same, but the curvature changes sign) [currently, such points
-   *      aren't handled in the auto-hinter]
+   *      aren't handled specially in the auto-hinter]
    *
-   *    `af_glyph_hints_align_strong_points' is the function which takes
+   *    `af_glyph_hints_align_strong_points' is the function that takes
    *    care of such situations; it is equivalent to the TrueType `IP'
    *    hinting instruction.
    *
@@ -211,46 +207,27 @@
 
 
   /* point hint flags */
-  typedef enum  AF_Flags_
-  {
-    AF_FLAG_NONE = 0,
+#define AF_FLAG_NONE  0
 
-    /* point type flags */
-    AF_FLAG_CONIC   = 1 << 0,
-    AF_FLAG_CUBIC   = 1 << 1,
-    AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC,
+  /* point type flags */
+#define AF_FLAG_CONIC    ( 1U << 0 )
+#define AF_FLAG_CUBIC    ( 1U << 1 )
+#define AF_FLAG_CONTROL  ( AF_FLAG_CONIC | AF_FLAG_CUBIC )
 
-    /* point extremum flags */
-    AF_FLAG_EXTREMA_X = 1 << 2,
-    AF_FLAG_EXTREMA_Y = 1 << 3,
+  /* point touch flags */
+#define AF_FLAG_TOUCH_X  ( 1U << 2 )
+#define AF_FLAG_TOUCH_Y  ( 1U << 3 )
 
-    /* point roundness flags */
-    AF_FLAG_ROUND_X = 1 << 4,
-    AF_FLAG_ROUND_Y = 1 << 5,
-
-    /* point touch flags */
-    AF_FLAG_TOUCH_X = 1 << 6,
-    AF_FLAG_TOUCH_Y = 1 << 7,
-
-    /* candidates for weak interpolation have this flag set */
-    AF_FLAG_WEAK_INTERPOLATION = 1 << 8,
-
-    /* all inflection points in the outline have this flag set */
-    AF_FLAG_INFLECTION = 1 << 9
-
-  } AF_Flags;
+  /* candidates for weak interpolation have this flag set */
+#define AF_FLAG_WEAK_INTERPOLATION  ( 1U << 4 )
 
 
   /* edge hint flags */
-  typedef enum  AF_Edge_Flags_
-  {
-    AF_EDGE_NORMAL  = 0,
-    AF_EDGE_ROUND   = 1 << 0,
-    AF_EDGE_SERIF   = 1 << 1,
-    AF_EDGE_DONE    = 1 << 2,
-    AF_EDGE_NEUTRAL = 1 << 3  /* set if edge aligns to a neutral blue zone */
-
-  } AF_Edge_Flags;
+#define AF_EDGE_NORMAL  0
+#define AF_EDGE_ROUND    ( 1U << 0 )
+#define AF_EDGE_SERIF    ( 1U << 1 )
+#define AF_EDGE_DONE     ( 1U << 2 )
+#define AF_EDGE_NEUTRAL  ( 1U << 3 ) /* edge aligns to a neutral blue zone */
 
 
   typedef struct AF_PointRec_*    AF_Point;
@@ -320,6 +297,8 @@
 
   } AF_EdgeRec;
 
+#define AF_SEGMENTS_EMBEDDED  18   /* number of embedded segments   */
+#define AF_EDGES_EMBEDDED     12   /* number of embedded edges      */
 
   typedef struct  AF_AxisHintsRec_
   {
@@ -336,9 +315,20 @@
 
     AF_Direction  major_dir;    /* either vertical or horizontal */
 
+    /* two arrays to avoid allocation penalty */
+    struct
+    {
+      AF_SegmentRec  segments[AF_SEGMENTS_EMBEDDED];
+      AF_EdgeRec     edges[AF_EDGES_EMBEDDED];
+    } embedded;
+
+
   } AF_AxisHintsRec, *AF_AxisHints;
 
 
+#define AF_POINTS_EMBEDDED     96   /* number of embedded points   */
+#define AF_CONTOURS_EMBEDDED    8   /* number of embedded contours */
+
   typedef struct  AF_GlyphHintsRec_
   {
     FT_Memory        memory;
@@ -367,6 +357,14 @@
     FT_Pos           xmin_delta;    /* used for warping */
     FT_Pos           xmax_delta;
 
+    /* Two arrays to avoid allocation penalty.            */
+    /* The `embedded' structure must be the last element! */
+    struct
+    {
+      AF_Point       contours[AF_CONTOURS_EMBEDDED];
+      AF_PointRec    points[AF_POINTS_EMBEDDED];
+    } embedded;
+
   } AF_GlyphHintsRec;
 
 
@@ -384,9 +382,6 @@
           ( !_af_debug_disable_vert_hints                          && \
             !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) )
 
-#define AF_HINTS_DO_ADVANCE( h )                                \
-          !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
-
 #define AF_HINTS_DO_BLUES( h )  ( !_af_debug_disable_blue_hints )
 
 #else /* !FT_DEBUG_AUTOFIT */
@@ -397,14 +392,19 @@
 #define AF_HINTS_DO_VERTICAL( h )                                \
           !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL )
 
-#define AF_HINTS_DO_ADVANCE( h )                                \
-          !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
-
 #define AF_HINTS_DO_BLUES( h )  1
 
 #endif /* !FT_DEBUG_AUTOFIT */
 
 
+#define AF_HINTS_DO_ADVANCE( h )                                \
+          !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_ADVANCE )
+
+#define AF_HINTS_DO_WARP( h )                                  \
+          !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_WARPER )
+
+
+
   FT_LOCAL( AF_Direction )
   af_direction_compute( FT_Pos  dx,
                         FT_Pos  dy );
diff --git a/src/autofit/afindic.c b/src/autofit/afindic.c
index 197881b..7412cd1 100644
--- a/src/autofit/afindic.c
+++ b/src/autofit/afindic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines for Indic writing system (body).        */
 /*                                                                         */
-/*  Copyright 2007, 2011-2013 by                                           */
+/*  Copyright 2007-2015 by                                                 */
 /*  Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>.    */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afindic.h b/src/autofit/afindic.h
index 9e13cf7..4c36908 100644
--- a/src/autofit/afindic.h
+++ b/src/autofit/afindic.h
@@ -5,7 +5,7 @@
 /*    Auto-fitter hinting routines for Indic writing system                */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2007, 2012, 2013 by                                          */
+/*  Copyright 2007-2015 by                                                 */
 /*  Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>.    */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index a1f2b33..893e986 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines for latin writing system (body).        */
 /*                                                                         */
-/*  Copyright 2003-2014 by                                                 */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -261,8 +261,8 @@
     FT_Pos        flats [AF_BLUE_STRING_MAX_LEN];
     FT_Pos        rounds[AF_BLUE_STRING_MAX_LEN];
 
-    FT_Int        num_flats;
-    FT_Int        num_rounds;
+    FT_UInt       num_flats;
+    FT_UInt       num_rounds;
 
     AF_LatinBlue  blue;
     FT_Error      error;
@@ -362,9 +362,10 @@
 
         error   = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
         outline = face->glyph->outline;
-        if ( error || outline.n_points <= 0 )
+        /* reject glyphs that don't produce any rendering */
+        if ( error || outline.n_points <= 2 )
         {
-          FT_TRACE5(( "  U+%04lX contains no outlines\n", ch ));
+          FT_TRACE5(( "  U+%04lX contains no (usable) outlines\n", ch ));
           continue;
         }
 
@@ -1293,17 +1294,19 @@
           /* this is the start of a new segment! */
           segment_dir = (AF_Direction)point->out_dir;
 
-          /* clear all segment fields */
           error = af_axis_hints_new_segment( axis, memory, &segment );
           if ( error )
             goto Exit;
 
-          segment[0]        = seg0;
+          /* clear all segment fields */
+          segment[0] = seg0;
+
           segment->dir      = (FT_Char)segment_dir;
           min_pos = max_pos = point->u;
           segment->first    = point;
           segment->last     = point;
-          on_edge           = 1;
+
+          on_edge = 1;
         }
 
         point = point->next;
@@ -1327,9 +1330,6 @@
         FT_Pos    last_v  = last->v;
 
 
-        if ( first == last )
-          continue;
-
         if ( first_v < last_v )
         {
           AF_Point  p;
@@ -1405,9 +1405,7 @@
     /* now compare each segment to the others */
     for ( seg1 = segments; seg1 < segment_limit; seg1++ )
     {
-      /* the fake segments are introduced to hint the metrics -- */
-      /* we must never link them to anything                     */
-      if ( seg1->dir != axis->major_dir || seg1->first == seg1->last )
+      if ( seg1->dir != axis->major_dir )
         continue;
 
       /* search for stems having opposite directions, */
@@ -1794,7 +1792,7 @@
         /*      Example: the `c' in cour.pfa at size 13     */
 
         if ( edge->serif && edge->link )
-          edge->serif = 0;
+          edge->serif = NULL;
       }
     }
 
@@ -1828,7 +1826,7 @@
 
   /* Compute all edges which lie within blue zones. */
 
-  FT_LOCAL_DEF( void )
+  static void
   af_latin_hints_compute_blue_edges( AF_GlyphHints    hints,
                                      AF_LatinMetrics  metrics )
   {
@@ -1998,11 +1996,20 @@
     /*
      *  In `light' hinting mode we disable horizontal hinting completely.
      *  We also do it if the face is italic.
+     *
+     *  However, if warping is enabled (which only works in `light' hinting
+     *  mode), advance widths get adjusted, too.
      */
     if ( mode == FT_RENDER_MODE_LIGHT                      ||
          ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 )
       scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;
 
+#ifdef AF_CONFIG_OPTION_USE_WARPER
+    /* get (global) warper flag */
+    if ( !metrics->root.globals->module->warping )
+      scaler_flags |= AF_SCALER_FLAG_NO_WARPER;
+#endif
+
     hints->scaler_flags = scaler_flags;
     hints->other_flags  = other_flags;
 
@@ -2023,13 +2030,13 @@
 
   static FT_Pos
   af_latin_snap_width( AF_Width  widths,
-                       FT_Int    count,
+                       FT_UInt   count,
                        FT_Pos    width )
   {
-    int     n;
-    FT_Pos  best      = 64 + 32 + 2;
-    FT_Pos  reference = width;
-    FT_Pos  scaled;
+    FT_UInt  n;
+    FT_Pos   best      = 64 + 32 + 2;
+    FT_Pos   reference = width;
+    FT_Pos   scaled;
 
 
     for ( n = 0; n < count; n++ )
@@ -2074,8 +2081,8 @@
   af_latin_compute_stem_width( AF_GlyphHints  hints,
                                AF_Dimension   dim,
                                FT_Pos         width,
-                               AF_Edge_Flags  base_flags,
-                               AF_Edge_Flags  stem_flags )
+                               FT_UInt        base_flags,
+                               FT_UInt        stem_flags )
   {
     AF_LatinMetrics  metrics  = (AF_LatinMetrics)hints->metrics;
     AF_LatinAxis     axis     = &metrics->axis[dim];
@@ -2242,10 +2249,9 @@
   {
     FT_Pos  dist = stem_edge->opos - base_edge->opos;
 
-    FT_Pos  fitted_width = af_latin_compute_stem_width(
-                             hints, dim, dist,
-                             (AF_Edge_Flags)base_edge->flags,
-                             (AF_Edge_Flags)stem_edge->flags );
+    FT_Pos  fitted_width = af_latin_compute_stem_width( hints, dim, dist,
+                                                        base_edge->flags,
+                                                        stem_edge->flags );
 
 
     stem_edge->pos = base_edge->pos + fitted_width;
@@ -2284,7 +2290,7 @@
 
   /* The main grid-fitting routine. */
 
-  FT_LOCAL_DEF( void )
+  static void
   af_latin_hint_edges( AF_GlyphHints  hints,
                        AF_Dimension   dim )
   {
@@ -2337,7 +2343,7 @@
           FT_Byte  neutral2 = edge2->flags & AF_EDGE_NEUTRAL;
 
 
-          if ( ( neutral && neutral2 ) || neutral2 )
+          if ( neutral2 )
           {
             edge2->blue_edge = NULL;
             edge2->flags    &= ~AF_EDGE_NEUTRAL;
@@ -2440,10 +2446,9 @@
 
 
         org_len = edge2->opos - edge->opos;
-        cur_len = af_latin_compute_stem_width(
-                    hints, dim, org_len,
-                    (AF_Edge_Flags)edge->flags,
-                    (AF_Edge_Flags)edge2->flags );
+        cur_len = af_latin_compute_stem_width( hints, dim, org_len,
+                                               edge->flags,
+                                               edge2->flags );
 
         /* some voodoo to specially round edges for small stem widths; */
         /* the idea is to align the center of a stem, then shifting    */
@@ -2510,10 +2515,9 @@
         org_len    = edge2->opos - edge->opos;
         org_center = org_pos + ( org_len >> 1 );
 
-        cur_len = af_latin_compute_stem_width(
-                    hints, dim, org_len,
-                    (AF_Edge_Flags)edge->flags,
-                    (AF_Edge_Flags)edge2->flags );
+        cur_len = af_latin_compute_stem_width( hints, dim, org_len,
+                                               edge->flags,
+                                               edge2->flags );
 
         if ( edge2->flags & AF_EDGE_DONE )
         {
@@ -2571,10 +2575,9 @@
           org_len    = edge2->opos - edge->opos;
           org_center = org_pos + ( org_len >> 1 );
 
-          cur_len    = af_latin_compute_stem_width(
-                         hints, dim, org_len,
-                         (AF_Edge_Flags)edge->flags,
-                         (AF_Edge_Flags)edge2->flags );
+          cur_len    = af_latin_compute_stem_width( hints, dim, org_len,
+                                                    edge->flags,
+                                                    edge2->flags );
 
           cur_pos1 = FT_PIX_ROUND( org_pos );
           delta1   = cur_pos1 + ( cur_len >> 1 ) - org_center;
@@ -2818,8 +2821,9 @@
 
     /* analyze glyph outline */
 #ifdef AF_CONFIG_OPTION_USE_WARPER
-    if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ||
-         AF_HINTS_DO_HORIZONTAL( hints )                          )
+    if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT &&
+           AF_HINTS_DO_WARP( hints )                                ) ||
+         AF_HINTS_DO_HORIZONTAL( hints )                              )
 #else
     if ( AF_HINTS_DO_HORIZONTAL( hints ) )
 #endif
@@ -2851,7 +2855,8 @@
     {
 #ifdef AF_CONFIG_OPTION_USE_WARPER
       if ( dim == AF_DIMENSION_HORZ                                 &&
-           metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT )
+           metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT &&
+           AF_HINTS_DO_WARP( hints )                                )
       {
         AF_WarperRec  warper;
         FT_Fixed      scale;
@@ -2864,7 +2869,7 @@
                                   scale, delta );
         continue;
       }
-#endif
+#endif /* AF_CONFIG_OPTION_USE_WARPER */
 
       if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) ||
            ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) )   )
diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h
index 2c0bfca..6855492 100644
--- a/src/autofit/aflatin.h
+++ b/src/autofit/aflatin.h
@@ -5,7 +5,7 @@
 /*    Auto-fitter hinting routines for latin writing system                */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2003-2007, 2009, 2011-2014 by                                */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -63,15 +63,11 @@
 #define AF_LATIN_MAX_WIDTHS  16
 
 
-  enum
-  {
-    AF_LATIN_BLUE_ACTIVE     = 1 << 0, /* set if zone height is <= 3/4px   */
-    AF_LATIN_BLUE_TOP        = 1 << 1, /* set if we have a top blue zone   */
-    AF_LATIN_BLUE_NEUTRAL    = 1 << 2, /* set if we have neutral blue zone */
-    AF_LATIN_BLUE_ADJUSTMENT = 1 << 3, /* used for scale adjustment        */
-                                       /* optimization                     */
-    AF_LATIN_BLUE_FLAG_MAX
-  };
+#define AF_LATIN_BLUE_ACTIVE      ( 1U << 0 ) /* zone height is <= 3/4px   */
+#define AF_LATIN_BLUE_TOP         ( 1U << 1 ) /* we have a top blue zone   */
+#define AF_LATIN_BLUE_NEUTRAL     ( 1U << 2 ) /* we have neutral blue zone */
+#define AF_LATIN_BLUE_ADJUSTMENT  ( 1U << 3 ) /* used for scale adjustment */
+                                              /* optimization              */
 
 
   typedef struct  AF_LatinBlueRec_
@@ -138,15 +134,11 @@
   /*************************************************************************/
   /*************************************************************************/
 
-  enum
-  {
-    AF_LATIN_HINTS_HORZ_SNAP   = 1 << 0, /* enable stem width snapping  */
-    AF_LATIN_HINTS_VERT_SNAP   = 1 << 1, /* enable stem height snapping */
-    AF_LATIN_HINTS_STEM_ADJUST = 1 << 2, /* enable stem width/height    */
-                                         /* adjustment                  */
-    AF_LATIN_HINTS_MONO        = 1 << 3  /* indicate monochrome         */
-                                         /* rendering                   */
-  };
+#define AF_LATIN_HINTS_HORZ_SNAP    ( 1U << 0 ) /* stem width snapping  */
+#define AF_LATIN_HINTS_VERT_SNAP    ( 1U << 1 ) /* stem height snapping */
+#define AF_LATIN_HINTS_STEM_ADJUST  ( 1U << 2 ) /* stem width/height    */
+                                                /* adjustment           */
+#define AF_LATIN_HINTS_MONO         ( 1U << 3 ) /* monochrome rendering */
 
 
 #define AF_LATIN_HINTS_DO_HORZ_SNAP( h )             \
diff --git a/src/autofit/aflatin2.c b/src/autofit/aflatin2.c
index 930fa98..ac9f933 100644
--- a/src/autofit/aflatin2.c
+++ b/src/autofit/aflatin2.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines for latin writing system (body).        */
 /*                                                                         */
-/*  Copyright 2003-2013 by                                                 */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -835,8 +835,8 @@
         {
           AF_Point  pt   = first;
           AF_Point  last = point;
-          AF_Flags  f0   = (AF_Flags)( pt->flags & AF_FLAG_CONTROL );
-          AF_Flags  f1;
+          FT_UInt   f0   = pt->flags & AF_FLAG_CONTROL;
+          FT_UInt   f1;
 
 
           segment->flags &= ~AF_EDGE_ROUND;
@@ -844,7 +844,7 @@
           for ( ; pt != last; f0 = f1 )
           {
             pt = pt->next;
-            f1 = (AF_Flags)( pt->flags & AF_FLAG_CONTROL );
+            f1 = pt->flags & AF_FLAG_CONTROL;
 
             if ( !f0 && !f1 )
               break;
@@ -890,9 +890,6 @@
         FT_Pos    last_v  = last->v;
 
 
-        if ( first == last )
-          continue;
-
         if ( first_v < last_v )
         {
           p = first->prev;
@@ -984,7 +981,7 @@
 #ifdef AF_SORT_SEGMENTS
     for ( seg1 = segments; seg1 < segment_mid; seg1++ )
     {
-      if ( seg1->dir != axis->major_dir || seg1->first == seg1->last )
+      if ( seg1->dir != axis->major_dir )
         continue;
 
       for ( seg2 = segment_mid; seg2 < segment_limit; seg2++ )
@@ -992,9 +989,7 @@
     /* now compare each segment to the others */
     for ( seg1 = segments; seg1 < segment_limit; seg1++ )
     {
-      /* the fake segments are introduced to hint the metrics -- */
-      /* we must never link them to anything                     */
-      if ( seg1->dir != axis->major_dir || seg1->first == seg1->last )
+      if ( seg1->dir != axis->major_dir )
         continue;
 
       for ( seg2 = segments; seg2 < segment_limit; seg2++ )
@@ -1053,7 +1048,7 @@
       {
         if ( seg2->link != seg1 )
         {
-          seg1->link  = 0;
+          seg1->link  = NULL;
           seg1->serif = seg2->link;
         }
       }
@@ -1133,7 +1128,7 @@
 
     for ( seg = segments; seg < segment_limit; seg++ )
     {
-      AF_Edge  found = 0;
+      AF_Edge  found = NULL;
       FT_Int   ee;
 
 
@@ -1194,9 +1189,10 @@
 
         edge->first    = seg;
         edge->last     = seg;
-        edge->fpos     = seg->pos;
         edge->dir      = seg->dir;
-        edge->opos     = edge->pos = FT_MulFix( seg->pos, scale );
+        edge->fpos     = seg->pos;
+        edge->opos     = FT_MulFix( seg->pos, scale );
+        edge->pos      = edge->opos;
         seg->edge_next = seg;
       }
       else
@@ -1359,7 +1355,7 @@
         /*      Example: the `c' in cour.pfa at size 13     */
 
         if ( edge->serif && edge->link )
-          edge->serif = 0;
+          edge->serif = NULL;
       }
     }
 
@@ -1386,7 +1382,7 @@
   }
 
 
-  FT_LOCAL_DEF( void )
+  static void
   af_latin2_hints_compute_blue_edges( AF_GlyphHints    hints,
                                       AF_LatinMetrics  metrics )
   {
@@ -1517,9 +1513,7 @@
 
 #if 0 /* #ifdef AF_CONFIG_OPTION_USE_WARPER */
     if ( mode == FT_RENDER_MODE_LCD || mode == FT_RENDER_MODE_LCD_V )
-    {
       metrics->root.scaler.render_mode = mode = FT_RENDER_MODE_NORMAL;
-    }
 #endif
 
     scaler_flags = hints->scaler_flags;
@@ -1556,6 +1550,12 @@
          ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 )
       scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;
 
+#ifdef AF_CONFIG_OPTION_USE_WARPER
+    /* get (global) warper flag */
+    if ( !metrics->root.globals->module->warping )
+      scaler_flags |= AF_SCALER_FLAG_NO_WARPER;
+#endif
+
     hints->scaler_flags = scaler_flags;
     hints->other_flags  = other_flags;
 
@@ -1576,13 +1576,13 @@
 
   static FT_Pos
   af_latin2_snap_width( AF_Width  widths,
-                        FT_Int    count,
+                        FT_UInt   count,
                         FT_Pos    width )
   {
-    int     n;
-    FT_Pos  best      = 64 + 32 + 2;
-    FT_Pos  reference = width;
-    FT_Pos  scaled;
+    FT_UInt  n;
+    FT_Pos   best      = 64 + 32 + 2;
+    FT_Pos   reference = width;
+    FT_Pos   scaled;
 
 
     for ( n = 0; n < count; n++ )
@@ -1625,8 +1625,8 @@
   af_latin2_compute_stem_width( AF_GlyphHints  hints,
                                 AF_Dimension   dim,
                                 FT_Pos         width,
-                                AF_Edge_Flags  base_flags,
-                                AF_Edge_Flags  stem_flags )
+                                FT_UInt        base_flags,
+                                FT_UInt        stem_flags )
   {
     AF_LatinMetrics  metrics  = (AF_LatinMetrics) hints->metrics;
     AF_LatinAxis     axis     = & metrics->axis[dim];
@@ -1797,10 +1797,9 @@
   {
     FT_Pos  dist = stem_edge->opos - base_edge->opos;
 
-    FT_Pos  fitted_width = af_latin2_compute_stem_width(
-                             hints, dim, dist,
-                             (AF_Edge_Flags)base_edge->flags,
-                             (AF_Edge_Flags)stem_edge->flags );
+    FT_Pos  fitted_width = af_latin2_compute_stem_width( hints, dim, dist,
+                                                         base_edge->flags,
+                                                         stem_edge->flags );
 
 
     stem_edge->pos = base_edge->pos + fitted_width;
@@ -1834,7 +1833,7 @@
   /*************************************************************************/
 
 
-  FT_LOCAL_DEF( void )
+  static void
   af_latin2_hint_edges( AF_GlyphHints  hints,
                         AF_Dimension   dim )
   {
@@ -1842,7 +1841,7 @@
     AF_Edge       edges      = axis->edges;
     AF_Edge       edge_limit = edges + axis->num_edges;
     AF_Edge       edge;
-    AF_Edge       anchor     = 0;
+    AF_Edge       anchor     = NULL;
     FT_Int        has_serifs = 0;
     FT_Pos        anchor_drift = 0;
 
@@ -1946,10 +1945,9 @@
 
 
         org_len = edge2->opos - edge->opos;
-        cur_len = af_latin2_compute_stem_width(
-                    hints, dim, org_len,
-                    (AF_Edge_Flags)edge->flags,
-                    (AF_Edge_Flags)edge2->flags );
+        cur_len = af_latin2_compute_stem_width( hints, dim, org_len,
+                                                edge->flags,
+                                                edge2->flags );
         if ( cur_len <= 64 )
           u_off = d_off = 32;
         else
@@ -2011,10 +2009,9 @@
         org_len    = edge2->opos - edge->opos;
         org_center = org_pos + ( org_len >> 1 );
 
-        cur_len = af_latin2_compute_stem_width(
-                   hints, dim, org_len,
-                   (AF_Edge_Flags)edge->flags,
-                   (AF_Edge_Flags)edge2->flags );
+        cur_len = af_latin2_compute_stem_width( hints, dim, org_len,
+                                                edge->flags,
+                                                edge2->flags );
 
         org_left  = org_pos + ( ( org_len - cur_len ) >> 1 );
         org_right = org_pos + ( ( org_len + cur_len ) >> 1 );
@@ -2317,8 +2314,9 @@
 
     /* analyze glyph outline */
 #ifdef AF_CONFIG_OPTION_USE_WARPER
-    if ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ||
-         AF_HINTS_DO_HORIZONTAL( hints ) )
+    if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT &&
+           AF_HINTS_DO_WARP( hints )                                ) ||
+         AF_HINTS_DO_HORIZONTAL( hints )                              )
 #else
     if ( AF_HINTS_DO_HORIZONTAL( hints ) )
 #endif
@@ -2341,8 +2339,9 @@
     for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
     {
 #ifdef AF_CONFIG_OPTION_USE_WARPER
-      if ( ( dim == AF_DIMENSION_HORZ &&
-             metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT ) )
+      if ( dim == AF_DIMENSION_HORZ                                 &&
+           metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT &&
+           AF_HINTS_DO_WARP( hints )                                )
       {
         AF_WarperRec  warper;
         FT_Fixed      scale;
@@ -2353,7 +2352,7 @@
         af_glyph_hints_scale_dim( hints, dim, scale, delta );
         continue;
       }
-#endif
+#endif /* AF_CONFIG_OPTION_USE_WARPER */
 
       if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) ||
            ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) )   )
diff --git a/src/autofit/aflatin2.h b/src/autofit/aflatin2.h
index b5d252a..9326753 100644
--- a/src/autofit/aflatin2.h
+++ b/src/autofit/aflatin2.h
@@ -5,7 +5,7 @@
 /*    Auto-fitter hinting routines for latin writing system                */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2003-2007, 2012, 2013 by                                     */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afloader.c b/src/autofit/afloader.c
index 0fa3c12..7c2fa7c 100644
--- a/src/autofit/afloader.c
+++ b/src/autofit/afloader.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter glyph loading routines (body).                           */
 /*                                                                         */
-/*  Copyright 2003-2009, 2011-2014 by                                      */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -26,38 +26,29 @@
 
   /* Initialize glyph loader. */
 
-  FT_LOCAL_DEF( FT_Error )
-  af_loader_init( AF_Module  module )
+  FT_LOCAL_DEF( void )
+  af_loader_init( AF_Loader      loader,
+                  AF_GlyphHints  hints )
   {
-    AF_Loader  loader = module->loader;
-    FT_Memory  memory = module->root.library->memory;
-
-
     FT_ZERO( loader );
 
-    af_glyph_hints_init( &loader->hints, memory );
-#ifdef FT_DEBUG_AUTOFIT
-    _af_debug_hints = &loader->hints;
-#endif
-    return FT_GlyphLoader_New( memory, &loader->gloader );
+    loader->hints = hints;
   }
 
 
   /* Reset glyph loader and compute globals if necessary. */
 
   FT_LOCAL_DEF( FT_Error )
-  af_loader_reset( AF_Module  module,
+  af_loader_reset( AF_Loader  loader,
+                   AF_Module  module,
                    FT_Face    face )
   {
-    FT_Error   error  = FT_Err_Ok;
-    AF_Loader  loader = module->loader;
+    FT_Error  error = FT_Err_Ok;
 
 
     loader->face    = face;
     loader->globals = (AF_FaceGlobals)face->autohint.data;
 
-    FT_GlyphLoader_Rewind( loader->gloader );
-
     if ( loader->globals == NULL )
     {
       error = af_face_globals_new( face, &loader->globals, module );
@@ -77,42 +68,33 @@
   /* Finalize glyph loader. */
 
   FT_LOCAL_DEF( void )
-  af_loader_done( AF_Module  module )
+  af_loader_done( AF_Loader  loader )
   {
-    AF_Loader  loader = module->loader;
-
-
-    af_glyph_hints_done( &loader->hints );
-
     loader->face    = NULL;
     loader->globals = NULL;
-
-#ifdef FT_DEBUG_AUTOFIT
-    _af_debug_hints = NULL;
-#endif
-    FT_GlyphLoader_Done( loader->gloader );
-    loader->gloader = NULL;
+    loader->hints   = NULL;
   }
 
 
-  /* Load a single glyph component.  This routine calls itself */
-  /* recursively, if necessary, and does the main work of      */
-  /* `af_loader_load_glyph.'                                   */
+  /* Do the main work of `af_loader_load_glyph'.  Note that we never   */
+  /* have to deal with composite glyphs as those get loaded into       */
+  /* FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. */
+  /* In the rare cases where FT_LOAD_NO_RECURSE is set, it implies     */
+  /* FT_LOAD_NO_SCALE and as such the auto-hinter is never called.     */
 
   static FT_Error
   af_loader_load_g( AF_Loader  loader,
                     AF_Scaler  scaler,
                     FT_UInt    glyph_index,
-                    FT_Int32   load_flags,
-                    FT_UInt    depth )
+                    FT_Int32   load_flags )
   {
     FT_Error          error;
     FT_Face           face     = loader->face;
-    FT_GlyphLoader    gloader  = loader->gloader;
     AF_StyleMetrics   metrics  = loader->metrics;
-    AF_GlyphHints     hints    = &loader->hints;
+    AF_GlyphHints     hints    = loader->hints;
     FT_GlyphSlot      slot     = face->glyph;
     FT_Slot_Internal  internal = slot->internal;
+    FT_GlyphLoader    gloader  = internal->loader;
     FT_Int32          flags;
 
 
@@ -131,8 +113,8 @@
       loader->trans_delta  = internal->glyph_delta;
 
       inverse = loader->trans_matrix;
-      FT_Matrix_Invert( &inverse );
-      FT_Vector_Transform( &loader->trans_delta, &inverse );
+      if ( !FT_Matrix_Invert( &inverse ) )
+        FT_Vector_Transform( &loader->trans_delta, &inverse );
     }
 
     switch ( slot->format )
@@ -144,29 +126,6 @@
                               loader->trans_delta.x,
                               loader->trans_delta.y );
 
-      /* copy the outline points in the loader's current                */
-      /* extra points which are used to keep original glyph coordinates */
-      error = FT_GLYPHLOADER_CHECK_POINTS( gloader,
-                                           slot->outline.n_points + 4,
-                                           slot->outline.n_contours );
-      if ( error )
-        goto Exit;
-
-      FT_ARRAY_COPY( gloader->current.outline.points,
-                     slot->outline.points,
-                     slot->outline.n_points );
-
-      FT_ARRAY_COPY( gloader->current.outline.contours,
-                     slot->outline.contours,
-                     slot->outline.n_contours );
-
-      FT_ARRAY_COPY( gloader->current.outline.tags,
-                     slot->outline.tags,
-                     slot->outline.n_points );
-
-      gloader->current.outline.n_points   = slot->outline.n_points;
-      gloader->current.outline.n_contours = slot->outline.n_contours;
-
       /* compute original horizontal phantom points (and ignore */
       /* vertical ones)                                         */
       loader->pp1.x = hints->x_delta;
@@ -192,7 +151,7 @@
 
         if ( writing_system_class->style_hints_apply )
           writing_system_class->style_hints_apply( hints,
-                                                   &gloader->current.outline,
+                                                   &gloader->base.outline,
                                                    metrics );
       }
 
@@ -267,128 +226,6 @@
         slot->rsb_delta = loader->pp2.x - pp2x;
       }
 
-      /* good, we simply add the glyph to our loader's base */
-      FT_GlyphLoader_Add( gloader );
-      break;
-
-    case FT_GLYPH_FORMAT_COMPOSITE:
-      {
-        FT_UInt      nn, num_subglyphs = slot->num_subglyphs;
-        FT_UInt      num_base_subgs, start_point;
-        FT_SubGlyph  subglyph;
-
-
-        start_point = gloader->base.outline.n_points;
-
-        /* first of all, copy the subglyph descriptors in the glyph loader */
-        error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs );
-        if ( error )
-          goto Exit;
-
-        FT_ARRAY_COPY( gloader->current.subglyphs,
-                       slot->subglyphs,
-                       num_subglyphs );
-
-        gloader->current.num_subglyphs = num_subglyphs;
-        num_base_subgs                 = gloader->base.num_subglyphs;
-
-        /* now read each subglyph independently */
-        for ( nn = 0; nn < num_subglyphs; nn++ )
-        {
-          FT_Vector  pp1, pp2;
-          FT_Pos     x, y;
-          FT_UInt    num_points, num_new_points, num_base_points;
-
-
-          /* gloader.current.subglyphs can change during glyph loading due */
-          /* to re-allocation -- we must recompute the current subglyph on */
-          /* each iteration                                                */
-          subglyph = gloader->base.subglyphs + num_base_subgs + nn;
-
-          pp1 = loader->pp1;
-          pp2 = loader->pp2;
-
-          num_base_points = gloader->base.outline.n_points;
-
-          error = af_loader_load_g( loader, scaler, subglyph->index,
-                                    load_flags, depth + 1 );
-          if ( error )
-            goto Exit;
-
-          /* recompute subglyph pointer */
-          subglyph = gloader->base.subglyphs + num_base_subgs + nn;
-
-          if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ) )
-          {
-            loader->pp1 = pp1;
-            loader->pp2 = pp2;
-          }
-
-          num_points     = gloader->base.outline.n_points;
-          num_new_points = num_points - num_base_points;
-
-          /* now perform the transformation required for this subglyph */
-
-          if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE    |
-                                   FT_SUBGLYPH_FLAG_XY_SCALE |
-                                   FT_SUBGLYPH_FLAG_2X2      ) )
-          {
-            FT_Vector*  cur   = gloader->base.outline.points +
-                                num_base_points;
-            FT_Vector*  limit = cur + num_new_points;
-
-
-            for ( ; cur < limit; cur++ )
-              FT_Vector_Transform( cur, &subglyph->transform );
-          }
-
-          /* apply offset */
-
-          if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )
-          {
-            FT_Int      k = subglyph->arg1;
-            FT_UInt     l = subglyph->arg2;
-            FT_Vector*  p1;
-            FT_Vector*  p2;
-
-
-            if ( start_point + k >= num_base_points         ||
-                               l >= (FT_UInt)num_new_points )
-            {
-              error = FT_THROW( Invalid_Composite );
-              goto Exit;
-            }
-
-            l += num_base_points;
-
-            /* for now, only use the current point coordinates; */
-            /* we eventually may consider another approach      */
-            p1 = gloader->base.outline.points + start_point + k;
-            p2 = gloader->base.outline.points + start_point + l;
-
-            x = p1->x - p2->x;
-            y = p1->y - p2->y;
-          }
-          else
-          {
-            x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta;
-            y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta;
-
-            x = FT_PIX_ROUND( x );
-            y = FT_PIX_ROUND( y );
-          }
-
-          {
-            FT_Outline  dummy = gloader->base.outline;
-
-
-            dummy.points  += num_base_points;
-            dummy.n_points = (short)num_new_points;
-
-            FT_Outline_Translate( &dummy, x, y );
-          }
-        }
-      }
       break;
 
     default:
@@ -397,7 +234,6 @@
     }
 
   Hint_Metrics:
-    if ( depth == 0 )
     {
       FT_BBox    bbox;
       FT_Vector  vvector;
@@ -472,18 +308,14 @@
       slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
       slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance );
 
-      /* now copy outline into glyph slot */
-      FT_GlyphLoader_Rewind( internal->loader );
-      error = FT_GlyphLoader_CopyPoints( internal->loader, gloader );
-      if ( error )
-        goto Exit;
-
+#if 0
       /* reassign all outline fields except flags to protect them */
       slot->outline.n_contours = internal->loader->base.outline.n_contours;
       slot->outline.n_points   = internal->loader->base.outline.n_points;
       slot->outline.points     = internal->loader->base.outline.points;
       slot->outline.tags       = internal->loader->base.outline.tags;
       slot->outline.contours   = internal->loader->base.outline.contours;
+#endif
 
       slot->format  = FT_GLYPH_FORMAT_OUTLINE;
     }
@@ -496,19 +328,19 @@
   /* Load a glyph. */
 
   FT_LOCAL_DEF( FT_Error )
-  af_loader_load_glyph( AF_Module  module,
+  af_loader_load_glyph( AF_Loader  loader,
+                        AF_Module  module,
                         FT_Face    face,
                         FT_UInt    gindex,
                         FT_Int32   load_flags )
   {
     FT_Error      error;
     FT_Size       size   = face->size;
-    AF_Loader     loader = module->loader;
     AF_ScalerRec  scaler;
 
 
     if ( !size )
-      return FT_THROW( Invalid_Argument );
+      return FT_THROW( Invalid_Size_Handle );
 
     FT_ZERO( &scaler );
 
@@ -521,7 +353,7 @@
     scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
     scaler.flags       = 0;  /* XXX: fix this */
 
-    error = af_loader_reset( module, face );
+    error = af_loader_reset( loader, module, face );
     if ( !error )
     {
       AF_StyleMetrics  metrics;
@@ -558,13 +390,13 @@
 
         if ( writing_system_class->style_hints_init )
         {
-          error = writing_system_class->style_hints_init( &loader->hints,
+          error = writing_system_class->style_hints_init( loader->hints,
                                                           metrics );
           if ( error )
             goto Exit;
         }
 
-        error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 );
+        error = af_loader_load_g( loader, &scaler, gindex, load_flags );
       }
     }
   Exit:
diff --git a/src/autofit/afloader.h b/src/autofit/afloader.h
index 9601e24..37cfd14 100644
--- a/src/autofit/afloader.h
+++ b/src/autofit/afloader.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter glyph loading routines (specification).                  */
 /*                                                                         */
-/*  Copyright 2003-2005, 2011-2013 by                                      */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -20,13 +20,12 @@
 #define __AFLOADER_H__
 
 #include "afhints.h"
+#include "afmodule.h"
 #include "afglobal.h"
 
 
 FT_BEGIN_HEADER
 
-  typedef struct AF_ModuleRec_*  AF_Module;
-
   /*
    *  The autofitter module's (global) data structure to communicate with
    *  actual fonts.  If necessary, `local' data like the current face, the
@@ -42,8 +41,7 @@
     AF_FaceGlobals    globals;
 
     /* current glyph data */
-    FT_GlyphLoader    gloader;
-    AF_GlyphHintsRec  hints;
+    AF_GlyphHints     hints;
     AF_StyleMetrics   metrics;
     FT_Bool           transformed;
     FT_Matrix         trans_matrix;
@@ -55,21 +53,24 @@
   } AF_LoaderRec, *AF_Loader;
 
 
-  FT_LOCAL( FT_Error )
-  af_loader_init( AF_Module  module );
+  FT_LOCAL( void )
+  af_loader_init( AF_Loader      loader,
+                  AF_GlyphHints  hints );
 
 
   FT_LOCAL( FT_Error )
-  af_loader_reset( AF_Module  module,
+  af_loader_reset( AF_Loader  loader,
+                   AF_Module  module,
                    FT_Face    face );
 
 
   FT_LOCAL( void )
-  af_loader_done( AF_Module  module );
+  af_loader_done( AF_Loader  loader );
 
 
   FT_LOCAL( FT_Error )
-  af_loader_load_glyph( AF_Module  module,
+  af_loader_load_glyph( AF_Loader  loader,
+                        AF_Module  module,
                         FT_Face    face,
                         FT_UInt    gindex,
                         FT_Int32   load_flags );
diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c
index 181cf55..8ae425c 100644
--- a/src/autofit/afmodule.c
+++ b/src/autofit/afmodule.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter module implementation (body).                            */
 /*                                                                         */
-/*  Copyright 2003-2006, 2009, 2011-2014 by                                */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -23,10 +23,27 @@
 #include "afpic.h"
 
 #ifdef FT_DEBUG_AUTOFIT
-  int    _af_debug_disable_horz_hints;
-  int    _af_debug_disable_vert_hints;
-  int    _af_debug_disable_blue_hints;
-  void*  _af_debug_hints;
+
+#ifndef FT_MAKE_OPTION_SINGLE_OBJECT
+  extern void
+  af_glyph_hints_dump_segments( AF_GlyphHints  hints,
+                                FT_Bool        to_stdout );
+  extern void
+  af_glyph_hints_dump_points( AF_GlyphHints  hints,
+                              FT_Bool        to_stdout );
+  extern void
+  af_glyph_hints_dump_edges( AF_GlyphHints  hints,
+                             FT_Bool        to_stdout );
+#endif
+
+  int  _af_debug_disable_horz_hints;
+  int  _af_debug_disable_vert_hints;
+  int  _af_debug_disable_blue_hints;
+
+  /* we use a global object instead of a local one for debugging */
+  AF_GlyphHintsRec  _af_debug_hints_rec[1];
+
+  void*  _af_debug_hints = _af_debug_hints_rec;
 #endif
 
 #include FT_INTERNAL_OBJECTS_H
@@ -55,7 +72,7 @@
 
 
     if ( !face )
-      return FT_THROW( Invalid_Argument );
+      return FT_THROW( Invalid_Face_Handle );
 
     globals = (AF_FaceGlobals)face->autohint.data;
     if ( !globals )
@@ -141,6 +158,17 @@
 
       return error;
     }
+#ifdef AF_CONFIG_OPTION_USE_WARPER
+    else if ( !ft_strcmp( property_name, "warping" ) )
+    {
+      FT_Bool*  warping = (FT_Bool*)value;
+
+
+      module->warping = *warping;
+
+      return error;
+    }
+#endif /* AF_CONFIG_OPTION_USE_WARPER */
 
     FT_TRACE0(( "af_property_set: missing property `%s'\n",
                 property_name ));
@@ -157,6 +185,9 @@
     AF_Module  module         = (AF_Module)ft_module;
     FT_UInt    fallback_style = module->fallback_style;
     FT_UInt    default_script = module->default_script;
+#ifdef AF_CONFIG_OPTION_USE_WARPER
+    FT_Bool    warping        = module->warping;
+#endif
 
 
     if ( !ft_strcmp( property_name, "glyph-to-script-map" ) )
@@ -203,8 +234,18 @@
 
       return error;
     }
+#ifdef AF_CONFIG_OPTION_USE_WARPER
+    else if ( !ft_strcmp( property_name, "warping" ) )
+    {
+      FT_Bool*  val = (FT_Bool*)value;
 
 
+      *val = warping;
+
+      return error;
+    }
+#endif /* AF_CONFIG_OPTION_USE_WARPER */
+
     FT_TRACE0(( "af_property_get: missing property `%s'\n",
                 property_name ));
     return FT_THROW( Missing_Property );
@@ -226,7 +267,7 @@
   af_get_interface( FT_Module    module,
                     const char*  module_interface )
   {
-    /* AF_SERVICES_GET derefers `library' in PIC mode */
+    /* AF_SERVICES_GET dereferences `library' in PIC mode */
 #ifdef FT_CONFIG_OPTION_PIC
     FT_Library  library;
 
@@ -252,18 +293,23 @@
 
     module->fallback_style = AF_STYLE_FALLBACK;
     module->default_script = AF_SCRIPT_DEFAULT;
+#ifdef AF_CONFIG_OPTION_USE_WARPER
+    module->warping        = 0;
+#endif
 
-    return af_loader_init( module );
+    return FT_Err_Ok;
   }
 
 
   FT_CALLBACK_DEF( void )
   af_autofitter_done( FT_Module  ft_module )      /* AF_Module */
   {
-    AF_Module  module = (AF_Module)ft_module;
+    FT_UNUSED( ft_module );
 
-
-    af_loader_done( module );
+#ifdef FT_DEBUG_AUTOFIT
+    if ( _af_debug_hints_rec->memory )
+      af_glyph_hints_done( _af_debug_hints_rec );
+#endif
   }
 
 
@@ -274,10 +320,56 @@
                             FT_UInt       glyph_index,
                             FT_Int32      load_flags )
   {
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = module->root.library->memory;
+
+#ifdef FT_DEBUG_AUTOFIT
+
+    /* in debug mode, we use a global object that survives this routine */
+
+    AF_GlyphHints  hints = _af_debug_hints_rec;
+    AF_LoaderRec   loader[1];
+
     FT_UNUSED( size );
 
-    return af_loader_load_glyph( module, slot->face,
-                                 glyph_index, load_flags );
+
+    if ( hints->memory )
+      af_glyph_hints_done( hints );
+
+    af_glyph_hints_init( hints, memory );
+    af_loader_init( loader, hints );
+
+    error = af_loader_load_glyph( loader, module, slot->face,
+                                  glyph_index, load_flags );
+
+    af_glyph_hints_dump_points( hints, 0 );
+    af_glyph_hints_dump_segments( hints, 0 );
+    af_glyph_hints_dump_edges( hints, 0 );
+
+    af_loader_done( loader );
+
+    return error;
+
+#else /* !FT_DEBUG_AUTOFIT */
+
+    AF_GlyphHintsRec  hints[1];
+    AF_LoaderRec      loader[1];
+
+    FT_UNUSED( size );
+
+
+    af_glyph_hints_init( hints, memory );
+    af_loader_init( loader, hints );
+
+    error = af_loader_load_glyph( loader, module, slot->face,
+                                  glyph_index, load_flags );
+
+    af_loader_done( loader );
+    af_glyph_hints_done( hints );
+
+    return error;
+
+#endif /* !FT_DEBUG_AUTOFIT */
   }
 
 
diff --git a/src/autofit/afmodule.h b/src/autofit/afmodule.h
index 20b7b9f..b9c2fd8 100644
--- a/src/autofit/afmodule.h
+++ b/src/autofit/afmodule.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter module implementation (specification).                   */
 /*                                                                         */
-/*  Copyright 2003-2005, 2009, 2012, 2013 by                               */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -23,17 +23,13 @@
 #include FT_INTERNAL_OBJECTS_H
 #include FT_MODULE_H
 
-#include "afloader.h"
-
 
 FT_BEGIN_HEADER
 
 
   /*
-   *  This is the `extended' FT_Module structure which holds the
-   *  autofitter's global data.  Right before hinting a glyph, the data
-   *  specific to the glyph's face (blue zones, stem widths, etc.) are
-   *  loaded into `loader' (see function `af_loader_reset').
+   *  This is the `extended' FT_Module structure that holds the
+   *  autofitter's global data.
    */
 
   typedef struct  AF_ModuleRec_
@@ -42,13 +38,14 @@
 
     FT_UInt       fallback_style;
     FT_UInt       default_script;
+#ifdef AF_CONFIG_OPTION_USE_WARPER
+    FT_Bool       warping;
+#endif
 
-    AF_LoaderRec  loader[1];
-
-  } AF_ModuleRec;
+  } AF_ModuleRec, *AF_Module;
 
 
-FT_DECLARE_MODULE(autofit_module_class)
+FT_DECLARE_MODULE( autofit_module_class )
 
 
 FT_END_HEADER
diff --git a/src/autofit/afpic.c b/src/autofit/afpic.c
index cb29fd7..5589e61 100644
--- a/src/autofit/afpic.c
+++ b/src/autofit/afpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for autofit module.  */
 /*                                                                         */
-/*  Copyright 2009-2014 by                                                 */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afpic.h b/src/autofit/afpic.h
index 9a68b4a..25071e3 100644
--- a/src/autofit/afpic.h
+++ b/src/autofit/afpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for autofit module.  */
 /*                                                                         */
-/*  Copyright 2009, 2011-2013 by                                           */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afranges.c b/src/autofit/afranges.c
index 139a4c1..c1e0afb 100644
--- a/src/autofit/afranges.c
+++ b/src/autofit/afranges.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter Unicode script ranges (body).                            */
 /*                                                                         */
-/*  Copyright 2013, 2014 by                                                */
+/*  Copyright 2013-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -19,6 +19,17 @@
 #include "afranges.h"
 
 
+  const AF_Script_UniRangeRec  af_arab_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0600UL,  0x06FFUL ),  /* Arabic                                 */
+    AF_UNIRANGE_REC(  0x0750UL,  0x07FFUL ),  /* Arabic Supplement                      */
+    AF_UNIRANGE_REC(  0x08A0UL,  0x08FFUL ),  /* Arabic Extended-A                      */
+    AF_UNIRANGE_REC(  0xFB50UL,  0xFDFFUL ),  /* Arabic Presentation Forms-A            */
+    AF_UNIRANGE_REC(  0xFE70UL,  0xFEFFUL ),  /* Arabic Presentation Forms-B            */
+    AF_UNIRANGE_REC( 0x1EE00UL, 0x1EEFFUL ),  /* Arabic Mathematical Alphabetic Symbols */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
   const AF_Script_UniRangeRec  af_cyrl_uniranges[] =
   {
     AF_UNIRANGE_REC(  0x0400UL,  0x04FFUL ),  /* Cyrillic            */
@@ -28,9 +39,19 @@
     AF_UNIRANGE_REC(       0UL,       0UL )
   };
 
+  /* there are some characters in the Devanagari Unicode block that are    */
+  /* generic to Indic scripts; we omit them so that their presence doesn't */
+  /* trigger Devanagari                                                    */
+
   const AF_Script_UniRangeRec  af_deva_uniranges[] =
   {
-    AF_UNIRANGE_REC(  0x0900UL,  0x097FUL ),  /* Devanagari       */
+    AF_UNIRANGE_REC(  0x0900UL,  0x093BUL ),  /* Devanagari       */
+    /* omitting U+093C nukta */
+    AF_UNIRANGE_REC(  0x093DUL,  0x0950UL ),
+    /* omitting U+0951 udatta, U+0952 anudatta */
+    AF_UNIRANGE_REC(  0x0953UL,  0x0963UL ),
+    /* omitting U+0964 danda, U+0965 double danda */
+    AF_UNIRANGE_REC(  0x0966UL,  0x097FUL ),
     AF_UNIRANGE_REC(  0x20B9UL,  0x20B9UL ),  /* (new) Rupee sign */
     AF_UNIRANGE_REC(       0UL,       0UL )
   };
@@ -82,6 +103,18 @@
     AF_UNIRANGE_REC( 0UL, 0UL )
   };
 
+  const AF_Script_UniRangeRec  af_telu_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0C00UL,  0x0C7FUL ),  /* Telugu */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_thai_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0E00UL,  0x0E7FUL ),  /* Thai */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
 #ifdef AF_CONFIG_OPTION_INDIC
 
   const AF_Script_UniRangeRec  af_beng_uniranges[] =
@@ -150,12 +183,6 @@
     AF_UNIRANGE_REC(       0UL,       0UL )
   };
 
-  const AF_Script_UniRangeRec  af_telu_uniranges[] =
-  {
-    AF_UNIRANGE_REC(  0x0C00UL,  0x0C7FUL ),  /* Telugu */
-    AF_UNIRANGE_REC(       0UL,       0UL )
-  };
-
   const AF_Script_UniRangeRec  af_tibt_uniranges[] =
   {
     AF_UNIRANGE_REC(  0x0F00UL,  0x0FFFUL ),  /* Tibetan */
diff --git a/src/autofit/afranges.h b/src/autofit/afranges.h
index fe5b2aa..7c78ab0 100644
--- a/src/autofit/afranges.h
+++ b/src/autofit/afranges.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter Unicode script ranges (specification).                   */
 /*                                                                         */
-/*  Copyright 2013, 2014 by                                                */
+/*  Copyright 2013-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afscript.h b/src/autofit/afscript.h
index a418b05..dfcc830 100644
--- a/src/autofit/afscript.h
+++ b/src/autofit/afscript.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter scripts (specification only).                            */
 /*                                                                         */
-/*  Copyright 2013, 2014 by                                                */
+/*  Copyright 2013-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -26,6 +26,11 @@
   /* script name tag, followed by a string of standard characters (to */
   /* derive the standard width and height of stems).                  */
 
+  SCRIPT( arab, ARAB,
+          "Arabic",
+          HB_SCRIPT_ARABIC,
+          0x644, 0x62D, 0x640 ) /* ل ح ـ */
+
   SCRIPT( cyrl, CYRL,
           "Cyrillic",
           HB_SCRIPT_CYRILLIC,
@@ -56,6 +61,17 @@
           HB_SCRIPT_INVALID,
           0x0, 0x0, 0x0 )
 
+  /* there are no simple forms for letters; we thus use two digit shapes */
+  SCRIPT( telu, TELU,
+          "Telugu",
+          HB_SCRIPT_TELUGU,
+          0xC66, 0xC67, 0x0 ) /* ౦ ౧ */
+
+  SCRIPT( thai, THAI,
+          "Thai",
+          HB_SCRIPT_THAI,
+          0xE32, 0xE45, 0xE50 ) /* า ๅ ๐ */
+
 #ifdef AF_CONFIG_OPTION_INDIC
 
   SCRIPT( beng, BENG,
@@ -113,11 +129,6 @@
           HB_SCRIPT_TAMIL,
           'o', 0x0, 0x0 ) /* XXX */
 
-  SCRIPT( telu, TELU,
-          "Telugu",
-          HB_SCRIPT_TELUGU,
-          'o', 0x0, 0x0 ) /* XXX */
-
   SCRIPT( tibt, TIBT,
           "Tibetan",
           HB_SCRIPT_TIBETAN,
diff --git a/src/autofit/afstyles.h b/src/autofit/afstyles.h
index 27fdd2e..bfd5bb9 100644
--- a/src/autofit/afstyles.h
+++ b/src/autofit/afstyles.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter styles (specification only).                             */
 /*                                                                         */
-/*  Copyright 2013, 2014 by                                                */
+/*  Copyright 2013-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -80,6 +80,14 @@
                        "default",                        \
                        DEFAULT )
 
+
+  STYLE( arab_dflt, ARAB_DFLT,
+         "Arabic default style",
+         AF_WRITING_SYSTEM_LATIN,
+         AF_SCRIPT_ARAB,
+         AF_BLUE_STRINGSET_ARAB,
+         AF_COVERAGE_DEFAULT )
+
   META_STYLE_LATIN( cyrl, CYRL, "Cyrillic" )
 
   META_STYLE_LATIN( grek, GREK, "Greek" )
@@ -115,6 +123,20 @@
          (AF_Blue_Stringset)0,
          AF_COVERAGE_DEFAULT )
 
+  STYLE( telu_dflt, TELU_DFLT,
+         "Telugu default style",
+         AF_WRITING_SYSTEM_LATIN,
+         AF_SCRIPT_TELU,
+         AF_BLUE_STRINGSET_TELU,
+         AF_COVERAGE_DEFAULT )
+
+  STYLE( thai_dflt, THAI_DFLT,
+         "Thai default style",
+         AF_WRITING_SYSTEM_LATIN,
+         AF_SCRIPT_THAI,
+         AF_BLUE_STRINGSET_THAI,
+         AF_COVERAGE_DEFAULT )
+
 #ifdef AF_CONFIG_OPTION_INDIC
 
   /* no blue stringset support for the Indic writing system yet */
@@ -138,7 +160,6 @@
   STYLE_DEFAULT_INDIC( sund, SUND, "Sundanese" )
   STYLE_DEFAULT_INDIC( sylo, SYLO, "Syloti Nagri" )
   STYLE_DEFAULT_INDIC( taml, TAML, "Tamil" )
-  STYLE_DEFAULT_INDIC( telu, TELU, "Telugu" )
   STYLE_DEFAULT_INDIC( tibt, TIBT, "Tibetan" )
 
 #endif /* AF_CONFIG_OPTION_INDIC */
diff --git a/src/autofit/aftypes.h b/src/autofit/aftypes.h
index 61badd1..78e3fd7 100644
--- a/src/autofit/aftypes.h
+++ b/src/autofit/aftypes.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter types (specification only).                              */
 /*                                                                         */
-/*  Copyright 2003-2009, 2011-2014 by                                      */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -138,11 +138,10 @@
     AF_Angle  _delta = (angle2) - (angle1);     \
                                                 \
                                                 \
-    _delta %= AF_ANGLE_2PI;                     \
-    if ( _delta < 0 )                           \
+    while ( _delta <= -AF_ANGLE_PI )            \
       _delta += AF_ANGLE_2PI;                   \
                                                 \
-    if ( _delta > AF_ANGLE_PI )                 \
+    while ( _delta > AF_ANGLE_PI )              \
       _delta -= AF_ANGLE_2PI;                   \
                                                 \
     result = _delta;                            \
@@ -168,13 +167,10 @@
    *  auto-hinted glyph image.
    */
 
-  typedef enum  AF_ScalerFlags_
-  {
-    AF_SCALER_FLAG_NO_HORIZONTAL = 1,  /* disable horizontal hinting */
-    AF_SCALER_FLAG_NO_VERTICAL   = 2,  /* disable vertical hinting   */
-    AF_SCALER_FLAG_NO_ADVANCE    = 4   /* disable advance hinting    */
-
-  } AF_ScalerFlags;
+#define AF_SCALER_FLAG_NO_HORIZONTAL  1U /* disable horizontal hinting */
+#define AF_SCALER_FLAG_NO_VERTICAL    2U /* disable vertical hinting   */
+#define AF_SCALER_FLAG_NO_ADVANCE     4U /* disable advance hinting    */
+#define AF_SCALER_FLAG_NO_WARPER      8U /* disable warper             */
 
 
   typedef struct  AF_ScalerRec_
diff --git a/src/autofit/afwarp.c b/src/autofit/afwarp.c
index 34a97ff..59af4f0 100644
--- a/src/autofit/afwarp.c
+++ b/src/autofit/afwarp.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter warping algorithm (body).                                */
 /*                                                                         */
-/*  Copyright 2006, 2007, 2011 by                                          */
+/*  Copyright 2006-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -76,10 +76,10 @@
                                FT_Pos        xx2,
                                AF_WarpScore  base_distort,
                                AF_Segment    segments,
-                               FT_UInt       num_segments )
+                               FT_Int        num_segments )
   {
     FT_Int        idx_min, idx_max, idx0;
-    FT_UInt       nn;
+    FT_Int        nn;
     AF_WarpScore  scores[65];
 
 
@@ -171,7 +171,7 @@
     FT_Fixed      org_scale;
     FT_Pos        org_delta;
 
-    FT_UInt       nn, num_points, num_segments;
+    FT_Int        nn, num_points, num_segments;
     FT_Int        X1, X2;
     FT_Int        w;
 
diff --git a/src/autofit/afwarp.h b/src/autofit/afwarp.h
index 7343fdd..5a6208a 100644
--- a/src/autofit/afwarp.h
+++ b/src/autofit/afwarp.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter warping algorithm (specification).                       */
 /*                                                                         */
-/*  Copyright 2006, 2007 by                                                */
+/*  Copyright 2006-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -25,7 +25,7 @@
 
 #define AF_WARPER_SCALE
 
-#define AF_WARPER_FLOOR( x )  ( (x) & ~63 )
+#define AF_WARPER_FLOOR( x )  ( (x) & ~TYPEOF( x )63 )
 #define AF_WARPER_CEIL( x )   AF_WARPER_FLOOR( (x) + 63 )
 
 
diff --git a/src/autofit/afwrtsys.h b/src/autofit/afwrtsys.h
index 8aa2ed9..4aa89d2 100644
--- a/src/autofit/afwrtsys.h
+++ b/src/autofit/afwrtsys.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter writing systems (specification only).                    */
 /*                                                                         */
-/*  Copyright 2013 by                                                      */
+/*  Copyright 2013-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/autofit.c b/src/autofit/autofit.c
index e2b9934..b6ed4a0 100644
--- a/src/autofit/autofit.c
+++ b/src/autofit/autofit.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter module (body).                                           */
 /*                                                                         */
-/*  Copyright 2003-2007, 2011, 2013 by                                     */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/hbshim.c b/src/autofit/hbshim.c
index cc04815..c9c1db0 100644
--- a/src/autofit/hbshim.c
+++ b/src/autofit/hbshim.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    HarfBuzz interface for accessing OpenType features (body).           */
 /*                                                                         */
-/*  Copyright 2013, 2014 by                                                */
+/*  Copyright 2013-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -187,7 +187,7 @@
     count = 0;
 #endif
 
-    for ( idx = -1; hb_set_next( gsub_lookups, &idx ); )
+    for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_lookups, &idx ); )
     {
 #ifdef FT_DEBUG_LEVEL_TRACE
       FT_TRACE4(( " %d", idx ));
@@ -218,7 +218,7 @@
     count = 0;
 #endif
 
-    for ( idx = -1; hb_set_next( gpos_lookups, &idx ); )
+    for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gpos_lookups, &idx ); )
     {
 #ifdef FT_DEBUG_LEVEL_TRACE
       FT_TRACE4(( " %d", idx ));
@@ -267,7 +267,8 @@
 
           GET_UTF8_CHAR( ch, p );
 
-          for ( idx = -1; hb_set_next( gsub_lookups, &idx ); )
+          for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_lookups,
+                                                         &idx ); )
           {
             hb_codepoint_t  gidx = FT_Get_Char_Index( globals->face, ch );
 
@@ -329,7 +330,7 @@
      * out whether a glyph gets shifted vertically, but this is something I
      * would like to avoid if not really necessary.
      *
-     * Note that we don't follow this logic for the default coverage. 
+     * Note that we don't follow this logic for the default coverage.
      * Complex scripts like Devanagari have mandatory GPOS features to
      * position many glyph elements, using mark-to-base or mark-to-ligature
      * tables; the number of glyphs missed due to condition (b) would be far
@@ -344,7 +345,7 @@
     count = 0;
 #endif
 
-    for ( idx = -1; hb_set_next( gsub_glyphs, &idx ); )
+    for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_glyphs, &idx ); )
     {
 #ifdef FT_DEBUG_LEVEL_TRACE
       if ( !( count % 10 ) )
@@ -441,7 +442,7 @@
 
     if ( feature )
     {
-      FT_UInt  upem = metrics->globals->face->units_per_EM;
+      FT_Int  upem = (FT_Int)metrics->globals->face->units_per_EM;
 
       hb_font_t*    font = metrics->globals->hb_font;
       hb_buffer_t*  buf  = hb_buffer_create();
diff --git a/src/autofit/hbshim.h b/src/autofit/hbshim.h
index 02f1513..5636ca6 100644
--- a/src/autofit/hbshim.h
+++ b/src/autofit/hbshim.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    HarfBuzz interface for accessing OpenType features (specification).  */
 /*                                                                         */
-/*  Copyright 2013 by                                                      */
+/*  Copyright 2013-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/basepic.c b/src/base/basepic.c
index aeb6fd5..9850ed9 100644
--- a/src/base/basepic.c
+++ b/src/base/basepic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for base.            */
 /*                                                                         */
-/*  Copyright 2009, 2012, 2013 by                                          */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/basepic.h b/src/base/basepic.h
index 329d7c8..51ecf9e 100644
--- a/src/base/basepic.h
+++ b/src/base/basepic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for base.            */
 /*                                                                         */
-/*  Copyright 2009 by                                                      */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftadvanc.c b/src/base/ftadvanc.c
index 5207847..f12908f 100644
--- a/src/base/ftadvanc.c
+++ b/src/base/ftadvanc.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Quick computation of advance widths (body).                          */
 /*                                                                         */
-/*  Copyright 2008, 2009, 2011, 2013 by                                    */
+/*  Copyright 2008-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -80,6 +80,9 @@
     if ( !face )
       return FT_THROW( Invalid_Face_Handle );
 
+    if ( !padvance )
+      return FT_THROW( Invalid_Argument );
+
     if ( gindex >= (FT_UInt)face->num_glyphs )
       return FT_THROW( Invalid_Glyph_Index );
 
@@ -118,6 +121,9 @@
     if ( !face )
       return FT_THROW( Invalid_Face_Handle );
 
+    if ( !padvances )
+      return FT_THROW( Invalid_Argument );
+
     num = (FT_UInt)face->num_glyphs;
     end = start + count;
     if ( start >= num || end < start || end > num )
diff --git a/src/base/ftapi.c b/src/base/ftapi.c
index 8914d1f..f22a181 100644
--- a/src/base/ftapi.c
+++ b/src/base/ftapi.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType compatibility functions (body).                         */
 /*                                                                         */
-/*  Copyright 2002 by                                                      */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftbase.c b/src/base/ftbase.c
index 5e5d70e..253dfb7 100644
--- a/src/base/ftbase.c
+++ b/src/base/ftbase.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Single object library component (body only).                         */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by       */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftbase.h b/src/base/ftbase.h
index 51a1db1..cb57f96 100644
--- a/src/base/ftbase.h
+++ b/src/base/ftbase.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType private functions used in base module (specification).  */
 /*                                                                         */
-/*  Copyright 2008, 2010 by                                                */
+/*  Copyright 2008-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya.      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftbbox.c b/src/base/ftbbox.c
index 8d3f383..10df98d 100644
--- a/src/base/ftbbox.c
+++ b/src/base/ftbbox.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType bbox computation (body).                                    */
 /*                                                                         */
-/*  Copyright 1996-2002, 2004, 2006, 2010, 2013 by                         */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used        */
@@ -42,16 +42,35 @@
   } TBBox_Rec;
 
 
+#define FT_UPDATE_BBOX( p, bbox ) \
+  FT_BEGIN_STMNT                  \
+    if ( p->x < bbox.xMin )       \
+      bbox.xMin = p->x;           \
+    if ( p->x > bbox.xMax )       \
+      bbox.xMax = p->x;           \
+    if ( p->y < bbox.yMin )       \
+      bbox.yMin = p->y;           \
+    if ( p->y > bbox.yMax )       \
+      bbox.yMax = p->y;           \
+  FT_END_STMNT
+
+#define CHECK_X( p, bbox )                         \
+          ( p->x < bbox.xMin || p->x > bbox.xMax )
+
+#define CHECK_Y( p, bbox )                         \
+          ( p->y < bbox.yMin || p->y > bbox.yMax )
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
   /*    BBox_Move_To                                                       */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    This function is used as a `move_to' and `line_to' emitter during  */
+  /*    This function is used as a `move_to' emitter during                */
   /*    FT_Outline_Decompose().  It simply records the destination point   */
-  /*    in `user->last'; no further computations are necessary since we    */
-  /*    use the cbox as the starting bbox which must be refined.           */
+  /*    in `user->last'. We also update bbox in case contour starts with   */
+  /*    an implicit `on' point.                                            */
   /*                                                                       */
   /* <Input>                                                               */
   /*    to   :: A pointer to the destination vector.                       */
@@ -66,17 +85,42 @@
   BBox_Move_To( FT_Vector*  to,
                 TBBox_Rec*  user )
   {
+    FT_UPDATE_BBOX( to, user->bbox );
+
     user->last = *to;
 
     return 0;
   }
 
 
-#define CHECK_X( p, bbox )  \
-          ( p->x < bbox.xMin || p->x > bbox.xMax )
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    BBox_Line_To                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is used as a `line_to' emitter during                */
+  /*    FT_Outline_Decompose().  It simply records the destination point   */
+  /*    in `user->last'; no further computations are necessary because     */
+  /*    bbox already contains both explicit ends of the line segment.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    to   :: A pointer to the destination vector.                       */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    user :: A pointer to the current walk context.                     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Always 0.  Needed for the interface only.                          */
+  /*                                                                       */
+  static int
+  BBox_Line_To( FT_Vector*  to,
+                TBBox_Rec*  user )
+  {
+    user->last = *to;
 
-#define CHECK_Y( p, bbox )  \
-          ( p->y < bbox.yMin || p->y > bbox.yMax )
+    return 0;
+  }
 
 
   /*************************************************************************/
@@ -155,8 +199,8 @@
                  FT_Vector*  to,
                  TBBox_Rec*  user )
   {
-    /* we don't need to check `to' since it is always an `on' point, thus */
-    /* within the bbox                                                    */
+    /* in case `to' is implicit and not included in bbox yet */
+    FT_UPDATE_BBOX( to, user->bbox );
 
     if ( CHECK_X( control, user->bbox ) )
       BBox_Conic_Check( user->last.x,
@@ -203,15 +247,51 @@
   /*    max :: The address of the current maximum.                         */
   /*                                                                       */
   static FT_Pos
-  update_cubic_max( FT_Pos  q1,
-                    FT_Pos  q2,
-                    FT_Pos  q3,
-                    FT_Pos  q4,
-                    FT_Pos  max )
+  cubic_peak( FT_Pos  q1,
+              FT_Pos  q2,
+              FT_Pos  q3,
+              FT_Pos  q4 )
   {
-    /* for a cubic segment to possibly reach new maximum, at least */
-    /* one of its off-points must stay above the current value     */
-    while ( q2 > max || q3 > max )
+    FT_Pos  peak = 0;
+    FT_Int  shift;
+
+
+    /* This function finds a peak of a cubic segment if it is above 0    */
+    /* using iterative bisection of the segment, or returns 0.           */
+    /* The fixed-point arithmetic of bisection is inherently stable      */
+    /* but may loose accuracy in the two lowest bits.  To compensate,    */
+    /* we upscale the segment if there is room.  Large values may need   */
+    /* to be downscaled to avoid overflows during bisection.             */
+    /* It is called with either q2 or q3 positive, which is necessary    */
+    /* for the peak to exist and avoids undefined FT_MSB.                */
+
+    shift = 27 - FT_MSB( (FT_UInt32)( FT_ABS( q1 ) |
+                                      FT_ABS( q2 ) |
+                                      FT_ABS( q3 ) |
+                                      FT_ABS( q4 ) ) );
+
+    if ( shift > 0 )
+    {
+      /* upscaling too much just wastes time */
+      if ( shift > 2 )
+        shift = 2;
+
+      q1 <<=  shift;
+      q2 <<=  shift;
+      q3 <<=  shift;
+      q4 <<=  shift;
+    }
+    else
+    {
+      q1 >>= -shift;
+      q2 >>= -shift;
+      q3 >>= -shift;
+      q4 >>= -shift;
+    }
+
+    /* for a peak to exist above 0, the cubic segment must have */
+    /* at least one of its control off-points above 0.          */
+    while ( q2 > 0 || q3 > 0 )
     {
       /* determine which half contains the maximum and split */
       if ( q1 + q2 > q3 + q4 ) /* first half */
@@ -240,17 +320,22 @@
       /* check whether either end reached the maximum */
       if ( q1 == q2 && q1 >= q3 )
       {
-        max = q1;
+        peak = q1;
         break;
       }
       if ( q3 == q4 && q2 <= q4 )
       {
-        max = q4;
+        peak = q4;
         break;
       }
     }
 
-    return max;
+    if ( shift > 0 )
+      peak >>=  shift;
+    else
+      peak <<= -shift;
+
+    return peak;
   }
 
 
@@ -262,65 +347,17 @@
                     FT_Pos*  min,
                     FT_Pos*  max )
   {
-    FT_Pos  nmin, nmax;
-    FT_Int  shift;
-
-
     /* This function is only called when a control off-point is outside  */
-    /* the bbox that contains all on-points.  It finds a local extremum  */
-    /* within the segment using iterative bisection of the segment.      */
-    /* The fixed-point arithmetic of bisection is inherently stable      */
-    /* but may loose accuracy in the two lowest bits.  To compensate,    */
-    /* we upscale the segment if there is room.  Large values may need   */
-    /* to be downscaled to avoid overflows during bisection.             */
-    /* The control off-point outside the bbox is likely to have the top  */
-    /* absolute value among arguments.                                   */
+    /* the bbox that contains all on-points.  So at least one of the     */
+    /* conditions below holds and cubic_peak is called with at least one */
+    /* non-zero argument.                                                */
 
-    shift = 27 - FT_MSB( FT_ABS( p2 ) | FT_ABS( p3 ) );
-
-    if ( shift > 0 )
-    {
-      /* upscaling too much just wastes time */
-      if ( shift > 2 )
-        shift = 2;
-
-      p1 <<=  shift;
-      p2 <<=  shift;
-      p3 <<=  shift;
-      p4 <<=  shift;
-      nmin = *min << shift;
-      nmax = *max << shift;
-    }
-    else
-    {
-      p1 >>= -shift;
-      p2 >>= -shift;
-      p3 >>= -shift;
-      p4 >>= -shift;
-      nmin = *min >> -shift;
-      nmax = *max >> -shift;
-    }
-
-    nmax =  update_cubic_max(  p1,  p2,  p3,  p4,  nmax );
+    if ( p2 > *max || p3 > *max )
+      *max += cubic_peak( p1 - *max, p2 - *max, p3 - *max, p4 - *max );
 
     /* now flip the signs to update the minimum */
-    nmin = -update_cubic_max( -p1, -p2, -p3, -p4, -nmin );
-
-    if ( shift > 0 )
-    {
-      nmin >>=  shift;
-      nmax >>=  shift;
-    }
-    else
-    {
-      nmin <<= -shift;
-      nmax <<= -shift;
-    }
-
-    if ( nmin < *min )
-      *min = nmin;
-    if ( nmax > *max )
-      *max = nmax;
+    if ( p2 < *min || p3 < *min )
+      *min -= cubic_peak( *min - p1, *min - p2, *min - p3, *min - p4 );
   }
 
 
@@ -385,22 +422,26 @@
     return 0;
   }
 
-FT_DEFINE_OUTLINE_FUNCS(bbox_interface,
+
+  FT_DEFINE_OUTLINE_FUNCS(bbox_interface,
     (FT_Outline_MoveTo_Func) BBox_Move_To,
-    (FT_Outline_LineTo_Func) BBox_Move_To,
+    (FT_Outline_LineTo_Func) BBox_Line_To,
     (FT_Outline_ConicTo_Func)BBox_Conic_To,
     (FT_Outline_CubicTo_Func)BBox_Cubic_To,
     0, 0
   )
 
+
   /* documentation is in ftbbox.h */
 
   FT_EXPORT_DEF( FT_Error )
   FT_Outline_Get_BBox( FT_Outline*  outline,
                        FT_BBox     *abbox )
   {
-    FT_BBox     cbox;
-    FT_BBox     bbox;
+    FT_BBox     cbox = {  0x7FFFFFFFL,  0x7FFFFFFFL,
+                         -0x7FFFFFFFL, -0x7FFFFFFFL };
+    FT_BBox     bbox = {  0x7FFFFFFFL,  0x7FFFFFFFL,
+                         -0x7FFFFFFFL, -0x7FFFFFFFL };
     FT_Vector*  vec;
     FT_UShort   n;
 
@@ -424,32 +465,13 @@
     /* coincide, we exit immediately.                             */
 
     vec = outline->points;
-    bbox.xMin = bbox.xMax = cbox.xMin = cbox.xMax = vec->x;
-    bbox.yMin = bbox.yMax = cbox.yMin = cbox.yMax = vec->y;
-    vec++;
 
-    for ( n = 1; n < outline->n_points; n++ )
+    for ( n = 0; n < outline->n_points; n++ )
     {
-      FT_Pos  x = vec->x;
-      FT_Pos  y = vec->y;
-
-
-      /* update control box */
-      if ( x < cbox.xMin ) cbox.xMin = x;
-      if ( x > cbox.xMax ) cbox.xMax = x;
-
-      if ( y < cbox.yMin ) cbox.yMin = y;
-      if ( y > cbox.yMax ) cbox.yMax = y;
+      FT_UPDATE_BBOX( vec, cbox);
 
       if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON )
-      {
-        /* update bbox for `on' points only */
-        if ( x < bbox.xMin ) bbox.xMin = x;
-        if ( x > bbox.xMax ) bbox.xMax = x;
-
-        if ( y < bbox.yMin ) bbox.yMin = y;
-        if ( y > bbox.yMax ) bbox.yMax = y;
-      }
+        FT_UPDATE_BBOX( vec, bbox);
 
       vec++;
     }
diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c
index 6542c79..a54572a 100644
--- a/src/base/ftbitmap.c
+++ b/src/base/ftbitmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility functions for bitmaps (body).                       */
 /*                                                                         */
-/*  Copyright 2004-2009, 2011, 2013, 2014 by                               */
+/*  Copyright 2004-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -31,9 +31,20 @@
   /* documentation is in ftbitmap.h */
 
   FT_EXPORT_DEF( void )
+  FT_Bitmap_Init( FT_Bitmap  *abitmap )
+  {
+    if ( abitmap )
+      *abitmap = null_bitmap;
+  }
+
+
+  /* deprecated function name; retained for ABI compatibility */
+
+  FT_EXPORT_DEF( void )
   FT_Bitmap_New( FT_Bitmap  *abitmap )
   {
-    *abitmap = null_bitmap;
+    if ( abitmap )
+      *abitmap = null_bitmap;
   }
 
 
@@ -44,25 +55,42 @@
                   const FT_Bitmap  *source,
                   FT_Bitmap        *target)
   {
-    FT_Memory  memory = library->memory;
+    FT_Memory  memory;
     FT_Error   error  = FT_Err_Ok;
-    FT_Int     pitch  = source->pitch;
-    FT_ULong   size;
 
+    FT_Int    pitch;
+    FT_ULong  size;
+
+    FT_Int  source_pitch_sign, target_pitch_sign;
+
+
+    if ( !library )
+      return FT_THROW( Invalid_Library_Handle );
+
+    if ( !source || !target )
+      return FT_THROW( Invalid_Argument );
 
     if ( source == target )
       return FT_Err_Ok;
 
+    source_pitch_sign = source->pitch < 0 ? -1 : 1;
+    target_pitch_sign = target->pitch < 0 ? -1 : 1;
+
     if ( source->buffer == NULL )
     {
       *target = *source;
+      if ( source_pitch_sign != target_pitch_sign )
+        target->pitch = -target->pitch;
 
       return FT_Err_Ok;
     }
 
+    memory = library->memory;
+    pitch  = source->pitch;
+
     if ( pitch < 0 )
       pitch = -pitch;
-    size = (FT_ULong)( pitch * source->rows );
+    size = (FT_ULong)pitch * source->rows;
 
     if ( target->buffer )
     {
@@ -70,9 +98,9 @@
       FT_ULong  target_size;
 
 
-      if ( target_pitch < 0  )
+      if ( target_pitch < 0 )
         target_pitch = -target_pitch;
-      target_size = (FT_ULong)( target_pitch * target->rows );
+      target_size = (FT_ULong)target_pitch * target->rows;
 
       if ( target_size != size )
         (void)FT_QREALLOC( target->buffer, target_size, size );
@@ -89,13 +117,35 @@
       *target = *source;
       target->buffer = p;
 
-      FT_MEM_COPY( target->buffer, source->buffer, size );
+      if ( source_pitch_sign == target_pitch_sign )
+        FT_MEM_COPY( target->buffer, source->buffer, size );
+      else
+      {
+        /* take care of bitmap flow */
+        FT_UInt   i;
+        FT_Byte*  s = source->buffer;
+        FT_Byte*  t = target->buffer;
+
+
+        t += (FT_ULong)pitch * ( target->rows - 1 );
+
+        for ( i = target->rows; i > 0; i-- )
+        {
+          FT_ARRAY_COPY( t, s, pitch );
+
+          s += pitch;
+          t -= pitch;
+        }
+      }
     }
 
     return error;
   }
 
 
+  /* Enlarge `bitmap' horizontally and vertically by `xpixels' */
+  /* and `ypixels', respectively.                              */
+
   static FT_Error
   ft_bitmap_assure_buffer( FT_Memory   memory,
                            FT_Bitmap*  bitmap,
@@ -106,7 +156,7 @@
     int             pitch;
     int             new_pitch;
     FT_UInt         bpp;
-    FT_Int          i, width, height;
+    FT_UInt         i, width, height;
     unsigned char*  buffer = NULL;
 
 
@@ -120,21 +170,21 @@
     {
     case FT_PIXEL_MODE_MONO:
       bpp       = 1;
-      new_pitch = ( width + xpixels + 7 ) >> 3;
+      new_pitch = (int)( ( width + xpixels + 7 ) >> 3 );
       break;
     case FT_PIXEL_MODE_GRAY2:
       bpp       = 2;
-      new_pitch = ( width + xpixels + 3 ) >> 2;
+      new_pitch = (int)( ( width + xpixels + 3 ) >> 2 );
       break;
     case FT_PIXEL_MODE_GRAY4:
       bpp       = 4;
-      new_pitch = ( width + xpixels + 1 ) >> 1;
+      new_pitch = (int)( ( width + xpixels + 1 ) >> 1 );
       break;
     case FT_PIXEL_MODE_GRAY:
     case FT_PIXEL_MODE_LCD:
     case FT_PIXEL_MODE_LCD_V:
       bpp       = 8;
-      new_pitch = ( width + xpixels );
+      new_pitch = (int)( width + xpixels );
       break;
     default:
       return FT_THROW( Invalid_Glyph_Format );
@@ -144,17 +194,17 @@
     if ( ypixels == 0 && new_pitch <= pitch )
     {
       /* zero the padding */
-      FT_Int  bit_width = pitch * 8;
-      FT_Int  bit_last  = ( width + xpixels ) * bpp;
+      FT_UInt  bit_width = (FT_UInt)pitch * 8;
+      FT_UInt  bit_last  = ( width + xpixels ) * bpp;
 
 
       if ( bit_last < bit_width )
       {
         FT_Byte*  line  = bitmap->buffer + ( bit_last >> 3 );
         FT_Byte*  end   = bitmap->buffer + pitch;
-        FT_Int    shift = bit_last & 7;
+        FT_UInt   shift = bit_last & 7;
         FT_UInt   mask  = 0xFF00U >> shift;
-        FT_Int    count = height;
+        FT_UInt   count = height;
 
 
         for ( ; count > 0; count--, line += pitch, end += pitch )
@@ -168,33 +218,38 @@
             write++;
           }
           if ( write < end )
-            FT_MEM_ZERO( write, end-write );
+            FT_MEM_ZERO( write, end - write );
         }
       }
 
       return FT_Err_Ok;
     }
 
+    /* otherwise allocate new buffer */
     if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) )
       return error;
 
+    /* new rows get added at the top of the bitmap, */
+    /* thus take care of the flow direction         */
     if ( bitmap->pitch > 0 )
     {
-      FT_Int  len = ( width * bpp + 7 ) >> 3;
+      FT_UInt  len = ( width * bpp + 7 ) >> 3;
 
 
       for ( i = 0; i < bitmap->rows; i++ )
-        FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ),
-                     bitmap->buffer + pitch * i, len );
+        FT_MEM_COPY( buffer + (FT_UInt)new_pitch * ( ypixels + i ),
+                     bitmap->buffer + (FT_UInt)pitch * i,
+                     len );
     }
     else
     {
-      FT_Int  len = ( width * bpp + 7 ) >> 3;
+      FT_UInt  len = ( width * bpp + 7 ) >> 3;
 
 
       for ( i = 0; i < bitmap->rows; i++ )
-        FT_MEM_COPY( buffer + new_pitch * i,
-                     bitmap->buffer + pitch * i, len );
+        FT_MEM_COPY( buffer + (FT_UInt)new_pitch * i,
+                     bitmap->buffer + (FT_UInt)pitch * i,
+                     len );
     }
 
     FT_FREE( bitmap->buffer );
@@ -220,7 +275,8 @@
   {
     FT_Error        error;
     unsigned char*  p;
-    FT_Int          i, x, y, pitch;
+    FT_Int          i, x, pitch;
+    FT_UInt         y;
     FT_Int          xstr, ystr;
 
 
@@ -248,17 +304,11 @@
     case FT_PIXEL_MODE_GRAY4:
       {
         FT_Bitmap  tmp;
-        FT_Int     align;
 
 
-        if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 )
-          align = ( bitmap->width + xstr + 3 ) / 4;
-        else
-          align = ( bitmap->width + xstr + 1 ) / 2;
-
-        FT_Bitmap_New( &tmp );
-
-        error = FT_Bitmap_Convert( library, bitmap, &tmp, align );
+        /* convert to 8bpp */
+        FT_Bitmap_Init( &tmp );
+        error = FT_Bitmap_Convert( library, bitmap, &tmp, 1 );
         if ( error )
           return error;
 
@@ -285,17 +335,19 @@
       return FT_Err_Ok;
     }
 
-    error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr );
+    error = ft_bitmap_assure_buffer( library->memory, bitmap,
+                                     (FT_UInt)xstr, (FT_UInt)ystr );
     if ( error )
       return error;
 
+    /* take care of bitmap flow */
     pitch = bitmap->pitch;
     if ( pitch > 0 )
       p = bitmap->buffer + pitch * ystr;
     else
     {
       pitch = -pitch;
-      p = bitmap->buffer + pitch * ( bitmap->rows - 1 );
+      p = bitmap->buffer + (FT_UInt)pitch * ( bitmap->rows - 1 );
     }
 
     /* for each row */
@@ -309,7 +361,7 @@
        */
       for ( x = pitch - 1; x >= 0; x-- )
       {
-        unsigned char tmp;
+        unsigned char  tmp;
 
 
         tmp = p[x];
@@ -324,7 +376,7 @@
               p[x] |= p[x - 1] << ( 8 - i );
 
 #if 0
-            if ( p[x] == 0xff )
+            if ( p[x] == 0xFF )
               break;
 #endif
           }
@@ -334,12 +386,12 @@
             {
               if ( p[x] + p[x - i] > bitmap->num_grays - 1 )
               {
-                p[x] = (unsigned char)(bitmap->num_grays - 1);
+                p[x] = (unsigned char)( bitmap->num_grays - 1 );
                 break;
               }
               else
               {
-                p[x] = (unsigned char)(p[x] + p[x-i]);
+                p[x] = (unsigned char)( p[x] + p[x - i] );
                 if ( p[x] == bitmap->num_grays - 1 )
                   break;
               }
@@ -368,8 +420,8 @@
       p += bitmap->pitch;
     }
 
-    bitmap->width += xstr;
-    bitmap->rows += ystr;
+    bitmap->width += (FT_UInt)xstr;
+    bitmap->rows += (FT_UInt)ystr;
 
     return FT_Err_Ok;
   }
@@ -378,11 +430,11 @@
   static FT_Byte
   ft_gray_for_premultiplied_srgb_bgra( const FT_Byte*  bgra )
   {
-    FT_Byte   a = bgra[3];
-    FT_ULong  l;
+    FT_UInt  a = bgra[3];
+    FT_UInt  l;
 
 
-    /* Short-circuit transparent color to avoid div-by-zero. */
+    /* Short-circuit transparent color to avoid division by zero. */
     if ( !a )
       return 0;
 
@@ -392,17 +444,17 @@
      * A gamma of 2.2 is fair to assume.  And then, we need to
      * undo the premultiplication too.
      *
-     * http://accessibility.kde.org/hsl-adjusted.php
+     *   http://accessibility.kde.org/hsl-adjusted.php
      *
      * We do the computation with integers only, applying a gamma of 2.0.
-     * The following will never overflow 32 bits; it is a scaled-up
-     * luminosity with premultiplication not yet undone. 
+     * We guarantee 32-bit arithmetic to avoid overflow but the resulting
+     * luminosity fits into 16 bits.
      *
      */
 
-    l =  4731UL /* 0.0722 * 65536 */ * bgra[0] * bgra[0] +
-        46871UL /* 0.7152 * 65536 */ * bgra[1] * bgra[1] +
-        13933UL /* 0.2126 * 65536 */ * bgra[2] * bgra[2];
+    l = (  4732UL /* 0.0722 * 65536 */ * bgra[0] * bgra[0] +
+          46871UL /* 0.7152 * 65536 */ * bgra[1] * bgra[1] +
+          13933UL /* 0.2126 * 65536 */ * bgra[2] * bgra[2] ) >> 16;
 
     /*
      * Final transparency can be determined as follows.
@@ -413,11 +465,11 @@
      *
      * So the formula is a * (1 - l) = a - l * a.
      *
-     * In the actual code, we undo premultiplication and scale down again.
+     * We still need to undo premultiplication by dividing l by a*a.
      *
      */
 
-    return a - (FT_Byte)( ( l / a ) >> 16 );
+    return (FT_Byte)( a - l / a );
   }
 
 
@@ -432,10 +484,16 @@
     FT_Error   error = FT_Err_Ok;
     FT_Memory  memory;
 
+    FT_Byte*  s;
+    FT_Byte*  t;
+
 
     if ( !library )
       return FT_THROW( Invalid_Library_Handle );
 
+    if ( !source || !target )
+      return FT_THROW( Invalid_Argument );
+
     memory = library->memory;
 
     switch ( source->pixel_mode )
@@ -448,13 +506,15 @@
     case FT_PIXEL_MODE_LCD_V:
     case FT_PIXEL_MODE_BGRA:
       {
-        FT_Int   pad;
-        FT_Long  old_size;
+        FT_Int    pad, old_target_pitch, target_pitch;
+        FT_ULong  old_size;
 
 
-        old_size = target->rows * target->pitch;
-        if ( old_size < 0 )
-          old_size = -old_size;
+        old_target_pitch = target->pitch;
+        if ( old_target_pitch < 0 )
+          old_target_pitch = -old_target_pitch;
+
+        old_size = target->rows * (FT_UInt)old_target_pitch;
 
         target->pixel_mode = FT_PIXEL_MODE_GRAY;
         target->rows       = source->rows;
@@ -463,21 +523,23 @@
         pad = 0;
         if ( alignment > 0 )
         {
-          pad = source->width % alignment;
+          pad = (FT_Int)source->width % alignment;
           if ( pad != 0 )
             pad = alignment - pad;
         }
 
-        target->pitch = source->width + pad;
+        target_pitch = (FT_Int)source->width + pad;
 
-        if ( target->pitch > 0                                     &&
-             (FT_ULong)target->rows > FT_ULONG_MAX / target->pitch )
+        if ( target_pitch > 0                                               &&
+             (FT_ULong)target->rows > FT_ULONG_MAX / (FT_ULong)target_pitch )
           return FT_THROW( Invalid_Argument );
 
-        if ( target->rows * target->pitch > old_size             &&
+        if ( target->rows * (FT_ULong)target_pitch > old_size              &&
              FT_QREALLOC( target->buffer,
-                          old_size, target->rows * target->pitch ) )
+                          old_size, target->rows * (FT_UInt)target_pitch ) )
           return error;
+
+        target->pitch = target->pitch < 0 ? -target_pitch : target_pitch;
       }
       break;
 
@@ -485,13 +547,20 @@
       error = FT_THROW( Invalid_Argument );
     }
 
+    s = source->buffer;
+    t = target->buffer;
+
+    /* take care of bitmap flow */
+    if ( source->pitch < 0 )
+      s -= source->pitch * (FT_Int)( source->rows - 1 );
+    if ( target->pitch < 0 )
+      t -= target->pitch * (FT_Int)( target->rows - 1 );
+
     switch ( source->pixel_mode )
     {
     case FT_PIXEL_MODE_MONO:
       {
-        FT_Byte*  s = source->buffer;
-        FT_Byte*  t = target->buffer;
-        FT_Int    i;
+        FT_UInt  i;
 
 
         target->num_grays = 2;
@@ -500,7 +569,7 @@
         {
           FT_Byte*  ss = s;
           FT_Byte*  tt = t;
-          FT_Int    j;
+          FT_UInt   j;
 
 
           /* get the full bytes */
@@ -548,12 +617,8 @@
     case FT_PIXEL_MODE_LCD:
     case FT_PIXEL_MODE_LCD_V:
       {
-        FT_Int    width   = source->width;
-        FT_Byte*  s       = source->buffer;
-        FT_Byte*  t       = target->buffer;
-        FT_Int    s_pitch = source->pitch;
-        FT_Int    t_pitch = target->pitch;
-        FT_Int    i;
+        FT_UInt  width = source->width;
+        FT_UInt  i;
 
 
         target->num_grays = 256;
@@ -562,8 +627,8 @@
         {
           FT_ARRAY_COPY( t, s, width );
 
-          s += s_pitch;
-          t += t_pitch;
+          s += source->pitch;
+          t += target->pitch;
         }
       }
       break;
@@ -571,9 +636,7 @@
 
     case FT_PIXEL_MODE_GRAY2:
       {
-        FT_Byte*  s = source->buffer;
-        FT_Byte*  t = target->buffer;
-        FT_Int    i;
+        FT_UInt  i;
 
 
         target->num_grays = 4;
@@ -582,7 +645,7 @@
         {
           FT_Byte*  ss = s;
           FT_Byte*  tt = t;
-          FT_Int    j;
+          FT_UInt   j;
 
 
           /* get the full bytes */
@@ -623,9 +686,7 @@
 
     case FT_PIXEL_MODE_GRAY4:
       {
-        FT_Byte*  s = source->buffer;
-        FT_Byte*  t = target->buffer;
-        FT_Int    i;
+        FT_UInt  i;
 
 
         target->num_grays = 16;
@@ -634,7 +695,7 @@
         {
           FT_Byte*  ss = s;
           FT_Byte*  tt = t;
-          FT_Int    j;
+          FT_UInt   j;
 
 
           /* get the full bytes */
@@ -659,13 +720,10 @@
       }
       break;
 
+
     case FT_PIXEL_MODE_BGRA:
       {
-        FT_Byte*  s       = source->buffer;
-        FT_Byte*  t       = target->buffer;
-        FT_Int    s_pitch = source->pitch;
-        FT_Int    t_pitch = target->pitch;
-        FT_Int    i;
+        FT_UInt  i;
 
 
         target->num_grays = 256;
@@ -674,7 +732,7 @@
         {
           FT_Byte*  ss = s;
           FT_Byte*  tt = t;
-          FT_Int    j;
+          FT_UInt   j;
 
 
           for ( j = source->width; j > 0; j-- )
@@ -685,8 +743,8 @@
             tt += 1;
           }
 
-          s += s_pitch;
-          t += t_pitch;
+          s += source->pitch;
+          t += target->pitch;
         }
       }
       break;
@@ -711,7 +769,7 @@
       FT_Error   error;
 
 
-      FT_Bitmap_New( &bitmap );
+      FT_Bitmap_Init( &bitmap );
       error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap );
       if ( error )
         return error;
diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c
index 4db43e0..dca0e1d 100644
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Arithmetic computations (body).                                      */
 /*                                                                         */
-/*  Copyright 1996-2006, 2008, 2012-2014 by                                */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -40,235 +40,7 @@
 #include FT_INTERNAL_OBJECTS_H
 
 
-#ifndef  FT_CONFIG_OPTION_NO_ASSEMBLER
-  /* Provide assembler fragments for performance-critical functions. */
-  /* These must be defined `static __inline__' with GCC.             */
-
-#if defined( __CC_ARM ) || defined( __ARMCC__ )  /* RVCT */
-
-#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm
-
-  /* documentation is in freetype.h */
-
-  static __inline FT_Int32
-  FT_MulFix_arm( FT_Int32  a,
-                 FT_Int32  b )
-  {
-    register FT_Int32  t, t2;
-
-
-    __asm
-    {
-      smull t2, t,  b,  a           /* (lo=t2,hi=t) = a*b */
-      mov   a,  t,  asr #31         /* a   = (hi >> 31) */
-      add   a,  a,  #0x8000         /* a  += 0x8000 */
-      adds  t2, t2, a               /* t2 += a */
-      adc   t,  t,  #0              /* t  += carry */
-      mov   a,  t2, lsr #16         /* a   = t2 >> 16 */
-      orr   a,  a,  t,  lsl #16     /* a  |= t << 16 */
-    }
-    return a;
-  }
-
-#endif /* __CC_ARM || __ARMCC__ */
-
-
-#ifdef __GNUC__
-
-#if defined( __arm__ )                                 && \
-    ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \
-    !( defined( __CC_ARM ) || defined( __ARMCC__ ) )
-
-#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm
-
-  /* documentation is in freetype.h */
-
-  static __inline__ FT_Int32
-  FT_MulFix_arm( FT_Int32  a,
-                 FT_Int32  b )
-  {
-    register FT_Int32  t, t2;
-
-
-    __asm__ __volatile__ (
-      "smull  %1, %2, %4, %3\n\t"       /* (lo=%1,hi=%2) = a*b */
-      "mov    %0, %2, asr #31\n\t"      /* %0  = (hi >> 31) */
-#if defined( __clang__ ) && defined( __thumb2__ )
-      "add.w  %0, %0, #0x8000\n\t"      /* %0 += 0x8000 */
-#else
-      "add    %0, %0, #0x8000\n\t"      /* %0 += 0x8000 */
-#endif
-      "adds   %1, %1, %0\n\t"           /* %1 += %0 */
-      "adc    %2, %2, #0\n\t"           /* %2 += carry */
-      "mov    %0, %1, lsr #16\n\t"      /* %0  = %1 >> 16 */
-      "orr    %0, %0, %2, lsl #16\n\t"  /* %0 |= %2 << 16 */
-      : "=r"(a), "=&r"(t2), "=&r"(t)
-      : "r"(a), "r"(b)
-      : "cc" );
-    return a;
-  }
-
-#endif /* __arm__                      && */
-       /* ( __thumb2__ || !__thumb__ ) && */
-       /* !( __CC_ARM || __ARMCC__ )      */
-
-
-#if defined( __i386__ )
-
-#define FT_MULFIX_ASSEMBLER  FT_MulFix_i386
-
-  /* documentation is in freetype.h */
-
-  static __inline__ FT_Int32
-  FT_MulFix_i386( FT_Int32  a,
-                  FT_Int32  b )
-  {
-    register FT_Int32  result;
-
-
-    __asm__ __volatile__ (
-      "imul  %%edx\n"
-      "movl  %%edx, %%ecx\n"
-      "sarl  $31, %%ecx\n"
-      "addl  $0x8000, %%ecx\n"
-      "addl  %%ecx, %%eax\n"
-      "adcl  $0, %%edx\n"
-      "shrl  $16, %%eax\n"
-      "shll  $16, %%edx\n"
-      "addl  %%edx, %%eax\n"
-      : "=a"(result), "=d"(b)
-      : "a"(a), "d"(b)
-      : "%ecx", "cc" );
-    return result;
-  }
-
-#endif /* i386 */
-
-#endif /* __GNUC__ */
-
-
-#ifdef _MSC_VER /* Visual C++ */
-
-#ifdef _M_IX86
-
-#define FT_MULFIX_ASSEMBLER  FT_MulFix_i386
-
-  /* documentation is in freetype.h */
-
-  static __inline FT_Int32
-  FT_MulFix_i386( FT_Int32  a,
-                  FT_Int32  b )
-  {
-    register FT_Int32  result;
-
-    __asm
-    {
-      mov eax, a
-      mov edx, b
-      imul edx
-      mov ecx, edx
-      sar ecx, 31
-      add ecx, 8000h
-      add eax, ecx
-      adc edx, 0
-      shr eax, 16
-      shl edx, 16
-      add eax, edx
-      mov result, eax
-    }
-    return result;
-  }
-
-#endif /* _M_IX86 */
-
-#endif /* _MSC_VER */
-
-
-#if defined( __GNUC__ ) && defined( __x86_64__ )
-
-#define FT_MULFIX_ASSEMBLER  FT_MulFix_x86_64
-
-  static __inline__ FT_Int32
-  FT_MulFix_x86_64( FT_Int32  a,
-                    FT_Int32  b )
-  {
-    /* Temporarily disable the warning that C90 doesn't support */
-    /* `long long'.                                             */
-#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wlong-long"
-#endif
-
-#if 1
-    /* Technically not an assembly fragment, but GCC does a really good */
-    /* job at inlining it and generating good machine code for it.      */
-    long long  ret, tmp;
-
-
-    ret  = (long long)a * b;
-    tmp  = ret >> 63;
-    ret += 0x8000 + tmp;
-
-    return (FT_Int32)( ret >> 16 );
-#else
-
-    /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine  */
-    /* code from the lines below.  The main issue is that `wide_a' is not  */
-    /* properly initialized by sign-extending `a'.  Instead, the generated */
-    /* machine code assumes that the register that contains `a' on input   */
-    /* can be used directly as a 64-bit value, which is wrong most of the  */
-    /* time.                                                               */
-    long long  wide_a = (long long)a;
-    long long  wide_b = (long long)b;
-    long long  result;
-
-
-    __asm__ __volatile__ (
-      "imul %2, %1\n"
-      "mov %1, %0\n"
-      "sar $63, %0\n"
-      "lea 0x8000(%1, %0), %0\n"
-      "sar $16, %0\n"
-      : "=&r"(result), "=&r"(wide_a)
-      : "r"(wide_b)
-      : "cc" );
-
-    return (FT_Int32)result;
-#endif
-
-#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
-#pragma GCC diagnostic pop
-#endif
-  }
-
-#endif /* __GNUC__ && __x86_64__ */
-
-#if defined( __GNUC__ )
-#if ( __GNUC__ > 3 ) || ( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 4 ) )
-
-#if FT_SIZEOF_INT == 4
-
-#define FT_MSB_BUILTIN( x )  ( 31 - __builtin_clz( x ) )
-
-#elif FT_SIZEOF_LONG == 4
-
-#define FT_MSB_BUILTIN( x )  ( 31 - __builtin_clzl( x ) )
-
-#endif
-
-#endif
-#endif /* __GNUC__ */
-
-#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
-
-
-#ifdef FT_CONFIG_OPTION_INLINE_MULFIX
 #ifdef FT_MULFIX_ASSEMBLER
-#define FT_MULFIX_INLINED  FT_MULFIX_ASSEMBLER
-#endif
-#endif
-
-#ifdef FT_MULFIX_INLINED
 #undef FT_MulFix
 #endif
 
@@ -296,6 +68,16 @@
 #define FT_COMPONENT  trace_calc
 
 
+  /* transfer sign leaving a positive number */
+#define FT_MOVE_SIGN( x, s ) \
+  FT_BEGIN_STMNT             \
+    if ( x < 0 )             \
+    {                        \
+      x = -x;                \
+      s = -s;                \
+    }                        \
+  FT_END_STMNT
+
   /* The following three functions are available regardless of whether */
   /* FT_LONG64 is defined.                                             */
 
@@ -304,8 +86,8 @@
   FT_EXPORT_DEF( FT_Fixed )
   FT_RoundFix( FT_Fixed  a )
   {
-    return ( a >= 0 ) ?   ( a + 0x8000L ) & ~0xFFFFL
-                      : -((-a + 0x8000L ) & ~0xFFFFL );
+    return a >= 0 ?   ( a + 0x8000L ) & ~0xFFFFL
+                  : -((-a + 0x8000L ) & ~0xFFFFL );
   }
 
 
@@ -314,8 +96,8 @@
   FT_EXPORT_DEF( FT_Fixed )
   FT_CeilFix( FT_Fixed  a )
   {
-    return ( a >= 0 ) ?   ( a + 0xFFFFL ) & ~0xFFFFL
-                      : -((-a + 0xFFFFL ) & ~0xFFFFL );
+    return a >= 0 ?   ( a + 0xFFFFL ) & ~0xFFFFL
+                  : -((-a + 0xFFFFL ) & ~0xFFFFL );
   }
 
 
@@ -324,54 +106,50 @@
   FT_EXPORT_DEF( FT_Fixed )
   FT_FloorFix( FT_Fixed  a )
   {
-    return ( a >= 0 ) ?   a & ~0xFFFFL
-                      : -((-a) & ~0xFFFFL );
+    return a >= 0 ?   a & ~0xFFFFL
+                  : -((-a) & ~0xFFFFL );
   }
 
+#ifndef FT_MSB
 
   FT_BASE_DEF ( FT_Int )
   FT_MSB( FT_UInt32 z )
   {
-#ifdef FT_MSB_BUILTIN
+    FT_Int  shift = 0;
 
-    return FT_MSB_BUILTIN( z );
-
-#else
-
-    FT_Int shift = 0;
 
     /* determine msb bit index in `shift' */
-    if ( z >= ( 1L << 16 ) )
+    if ( z & 0xFFFF0000UL )
     {
       z     >>= 16;
       shift  += 16;
     }
-    if ( z >= ( 1L << 8 ) )
+    if ( z & 0x0000FF00UL )
     {
       z     >>= 8;
       shift  += 8;
     }
-    if ( z >= ( 1L << 4 ) )
+    if ( z & 0x000000F0UL )
     {
       z     >>= 4;
       shift  += 4;
     }
-    if ( z >= ( 1L << 2 ) )
+    if ( z & 0x0000000CUL )
     {
       z     >>= 2;
       shift  += 2;
     }
-    if ( z >= ( 1L << 1 ) )
+    if ( z & 0x00000002UL )
     {
    /* z     >>= 1; */
       shift  += 1;
     }
 
     return shift;
-
-#endif /* FT_MSB_BUILTIN */
   }
 
+#endif /* !FT_MSB */
+
 
   /* documentation is in ftcalc.h */
 
@@ -395,80 +173,89 @@
   /* documentation is in freetype.h */
 
   FT_EXPORT_DEF( FT_Long )
-  FT_MulDiv( FT_Long  a,
-             FT_Long  b,
-             FT_Long  c )
+  FT_MulDiv( FT_Long  a_,
+             FT_Long  b_,
+             FT_Long  c_ )
   {
-    FT_Int   s;
-    FT_Long  d;
+    FT_Int     s = 1;
+    FT_UInt64  a, b, c, d;
+    FT_Long    d_;
 
 
-    s = 1;
-    if ( a < 0 ) { a = -a; s = -1; }
-    if ( b < 0 ) { b = -b; s = -s; }
-    if ( c < 0 ) { c = -c; s = -s; }
+    FT_MOVE_SIGN( a_, s );
+    FT_MOVE_SIGN( b_, s );
+    FT_MOVE_SIGN( c_, s );
 
-    d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c
-                         : 0x7FFFFFFFL );
+    a = (FT_UInt64)a_;
+    b = (FT_UInt64)b_;
+    c = (FT_UInt64)c_;
 
-    return ( s > 0 ) ? d : -d;
+    d = c > 0 ? ( a * b + ( c >> 1 ) ) / c
+              : 0x7FFFFFFFUL;
+
+    d_ = (FT_Long)d;
+
+    return s < 0 ? -d_ : d_;
   }
 
 
   /* documentation is in ftcalc.h */
 
   FT_BASE_DEF( FT_Long )
-  FT_MulDiv_No_Round( FT_Long  a,
-                      FT_Long  b,
-                      FT_Long  c )
+  FT_MulDiv_No_Round( FT_Long  a_,
+                      FT_Long  b_,
+                      FT_Long  c_ )
   {
-    FT_Int   s;
-    FT_Long  d;
+    FT_Int     s = 1;
+    FT_UInt64  a, b, c, d;
+    FT_Long    d_;
 
 
-    s = 1;
-    if ( a < 0 ) { a = -a; s = -1; }
-    if ( b < 0 ) { b = -b; s = -s; }
-    if ( c < 0 ) { c = -c; s = -s; }
+    FT_MOVE_SIGN( a_, s );
+    FT_MOVE_SIGN( b_, s );
+    FT_MOVE_SIGN( c_, s );
 
-    d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c
-                         : 0x7FFFFFFFL );
+    a = (FT_UInt64)a_;
+    b = (FT_UInt64)b_;
+    c = (FT_UInt64)c_;
 
-    return ( s > 0 ) ? d : -d;
+    d = c > 0 ? a * b / c
+              : 0x7FFFFFFFUL;
+
+    d_ = (FT_Long)d;
+
+    return s < 0 ? -d_ : d_;
   }
 
 
   /* documentation is in freetype.h */
 
   FT_EXPORT_DEF( FT_Long )
-  FT_MulFix( FT_Long  a,
-             FT_Long  b )
+  FT_MulFix( FT_Long  a_,
+             FT_Long  b_ )
   {
 #ifdef FT_MULFIX_ASSEMBLER
 
-    return FT_MULFIX_ASSEMBLER( a, b );
+    return FT_MULFIX_ASSEMBLER( a_, b_ );
 
 #else
 
-    FT_Int   s = 1;
-    FT_Long  c;
+    FT_Int     s = 1;
+    FT_UInt64  a, b, c;
+    FT_Long    c_;
 
 
-    if ( a < 0 )
-    {
-      a = -a;
-      s = -1;
-    }
+    FT_MOVE_SIGN( a_, s );
+    FT_MOVE_SIGN( b_, s );
 
-    if ( b < 0 )
-    {
-      b = -b;
-      s = -s;
-    }
+    a = (FT_UInt64)a_;
+    b = (FT_UInt64)b_;
 
-    c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 );
+    c = ( a * b + 0x8000UL ) >> 16;
 
-    return ( s > 0 ) ? c : -c;
+    c_ = (FT_Long)c;
+
+    return s < 0 ? -c_ : c_;
 
 #endif /* FT_MULFIX_ASSEMBLER */
   }
@@ -477,33 +264,26 @@
   /* documentation is in freetype.h */
 
   FT_EXPORT_DEF( FT_Long )
-  FT_DivFix( FT_Long  a,
-             FT_Long  b )
+  FT_DivFix( FT_Long  a_,
+             FT_Long  b_ )
   {
-    FT_Int32   s;
-    FT_UInt32  q;
+    FT_Int     s = 1;
+    FT_UInt64  a, b, q;
+    FT_Long    q_;
 
 
-    s = 1;
-    if ( a < 0 )
-    {
-      a = -a;
-      s = -1;
-    }
-    if ( b < 0 )
-    {
-      b = -b;
-      s = -s;
-    }
+    FT_MOVE_SIGN( a_, s );
+    FT_MOVE_SIGN( b_, s );
 
-    if ( b == 0 )
-      /* check for division by 0 */
-      q = 0x7FFFFFFFL;
-    else
-      /* compute result directly */
-      q = (FT_UInt32)( ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b );
+    a = (FT_UInt64)a_;
+    b = (FT_UInt64)b_;
 
-    return ( s < 0 ? -(FT_Long)q : (FT_Long)q );
+    q = b > 0 ? ( ( a << 16 ) + ( b >> 1 ) ) / b
+              : 0x7FFFFFFFUL;
+
+    q_ = (FT_Long)q;
+
+    return s < 0 ? -q_ : q_;
   }
 
 
@@ -551,25 +331,30 @@
     FT_Int     i;
 
 
-    q = 0;
-    r = hi;
-
-    if ( r >= y )
+    if ( hi >= y )
       return (FT_UInt32)0x7FFFFFFFL;
 
-    i = 32;
+    /* We shift as many bits as we can into the high register, perform     */
+    /* 32-bit division with modulo there, then work through the remaining  */
+    /* bits with long division. This optimization is especially noticeable */
+    /* for smaller dividends that barely use the high register.            */
+
+    i = 31 - FT_MSB( hi );
+    r = ( hi << i ) | ( lo >> ( 32 - i ) ); lo <<= i; /* left 64-bit shift */
+    q = r / y;
+    r -= q * y;   /* remainder */
+
+    i = 32 - i;   /* bits remaining in low register */
     do
     {
-      r <<= 1;
       q <<= 1;
-      r  |= lo >> 31;
+      r   = ( r << 1 ) | ( lo >> 31 ); lo <<= 1;
 
       if ( r >= y )
       {
         r -= y;
         q |= 1;
       }
-      lo <<= 1;
     } while ( --i );
 
     return q;
@@ -581,7 +366,7 @@
             FT_Int64*  y,
             FT_Int64  *z )
   {
-    register FT_UInt32  lo, hi;
+    FT_UInt32  lo, hi;
 
 
     lo = x->lo + y->lo;
@@ -592,111 +377,161 @@
   }
 
 
-  /* documentation is in freetype.h */
-
-  /* The FT_MulDiv function has been optimized thanks to ideas from      */
-  /* Graham Asher and Alexei Podtelezhnikov.  The trick is to optimize   */
-  /* a rather common case when everything fits within 32-bits.           */
+  /*  The FT_MulDiv function has been optimized thanks to ideas from     */
+  /*  Graham Asher and Alexei Podtelezhnikov.  The trick is to optimize  */
+  /*  a rather common case when everything fits within 32-bits.          */
   /*                                                                     */
-  /*  We compute 'a*b+c/2', then divide it by 'c'. (positive values)     */
+  /*  We compute 'a*b+c/2', then divide it by 'c' (all positive values). */
   /*                                                                     */
   /*  The product of two positive numbers never exceeds the square of    */
-  /*  their mean.  Therefore, we always avoid the overflow by imposing   */
+  /*  its mean values.  Therefore, we always avoid the overflow by       */
+  /*  imposing                                                           */
   /*                                                                     */
-  /*  ( a + b ) / 2 <= sqrt( X - c/2 )                                   */
+  /*    (a + b) / 2 <= sqrt(X - c/2)    ,                                */
   /*                                                                     */
-  /*  where X = 2^31 - 1.  Now we replace sqrt with a linear function    */
-  /*  that is smaller or equal in the entire range of c from 0 to X;     */
-  /*  it should be equal to sqrt(X) and sqrt(X/2) at the range termini.  */
-  /*  Substituting the linear solution and explicit numbers we get       */
+  /*  where X = 2^32 - 1, the maximum unsigned 32-bit value, and using   */
+  /*  unsigned arithmetic.  Now we replace `sqrt' with a linear function */
+  /*  that is smaller or equal for all values of c in the interval       */
+  /*  [0;X/2]; it should be equal to sqrt(X) and sqrt(3X/4) at the       */
+  /*  endpoints.  Substituting the linear solution and explicit numbers  */
+  /*  we get                                                             */
   /*                                                                     */
-  /*  a + b <= 92681.9 - c / 79108.95                                    */
+  /*    a + b <= 131071.99 - c / 122291.84    .                          */
   /*                                                                     */
-  /*  In practice we use a faster and even stronger inequality           */
+  /*  In practice, we should use a faster and even stronger inequality   */
   /*                                                                     */
-  /*  a + b <= 92681 - (c >> 16)                                         */
+  /*    a + b <= 131071 - (c >> 16)                                      */
   /*                                                                     */
+  /*  or, alternatively,                                                 */
+  /*                                                                     */
+  /*    a + b <= 129894 - (c >> 17)    .                                 */
+  /*                                                                     */
+  /*  FT_MulFix, on the other hand, is optimized for a small value of    */
+  /*  the first argument, when the second argument can be much larger.   */
+  /*  This can be achieved by scaling the second argument and the limit  */
+  /*  in the above inequalities.  For example,                           */
+  /*                                                                     */
+  /*    a + (b >> 8) <= (131071 >> 4)                                    */
+  /*                                                                     */
+  /*  covers the practical range of use. The actual test below is a bit  */
+  /*  tighter to avoid the border case overflows.                        */
+  /*                                                                     */
+  /*  In the case of FT_DivFix, the exact overflow check                 */
+  /*                                                                     */
+  /*    a << 16 <= X - c/2                                               */
+  /*                                                                     */
+  /*  is scaled down by 2^16 and we use                                  */
+  /*                                                                     */
+  /*    a <= 65535 - (c >> 17)    .                                      */
+
+  /* documentation is in freetype.h */
 
   FT_EXPORT_DEF( FT_Long )
-  FT_MulDiv( FT_Long  a,
-             FT_Long  b,
-             FT_Long  c )
+  FT_MulDiv( FT_Long  a_,
+             FT_Long  b_,
+             FT_Long  c_ )
   {
-    long  s;
+    FT_Int     s = 1;
+    FT_UInt32  a, b, c;
 
 
     /* XXX: this function does not allow 64-bit arguments */
-    if ( a == 0 || b == c )
-      return a;
 
-    s  = a; a = FT_ABS( a );
-    s ^= b; b = FT_ABS( b );
-    s ^= c; c = FT_ABS( c );
+    if ( a_ == 0 || b_ == c_ )
+      return a_;
 
-    if ( (FT_ULong)a + (FT_ULong)b <= 92681UL - ( c >> 16 ) && c > 0 )
+    FT_MOVE_SIGN( a_, s );
+    FT_MOVE_SIGN( b_, s );
+    FT_MOVE_SIGN( c_, s );
+
+    a = (FT_UInt32)a_;
+    b = (FT_UInt32)b_;
+    c = (FT_UInt32)c_;
+
+    if ( c == 0 )
+      a = 0x7FFFFFFFUL;
+
+    else if ( a + b <= 129894UL - ( c >> 17 ) )
       a = ( a * b + ( c >> 1 ) ) / c;
 
-    else if ( (FT_Int32)c > 0 )
+    else
     {
       FT_Int64  temp, temp2;
 
 
-      ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp );
+      ft_multo64( a, b, &temp );
 
       temp2.hi = 0;
-      temp2.lo = (FT_UInt32)(c >> 1);
-      FT_Add64( &temp, &temp2, &temp );
-      a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c );
-    }
-    else
-      a = 0x7FFFFFFFL;
+      temp2.lo = c >> 1;
 
-    return ( s < 0 ? -a : a );
+      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_ = (FT_Long)a;
+
+    return s < 0 ? -a_ : a_;
   }
 
 
   FT_BASE_DEF( FT_Long )
-  FT_MulDiv_No_Round( FT_Long  a,
-                      FT_Long  b,
-                      FT_Long  c )
+  FT_MulDiv_No_Round( FT_Long  a_,
+                      FT_Long  b_,
+                      FT_Long  c_ )
   {
-    long  s;
+    FT_Int     s = 1;
+    FT_UInt32  a, b, c;
 
 
-    if ( a == 0 || b == c )
-      return a;
+    /* XXX: this function does not allow 64-bit arguments */
 
-    s  = a; a = FT_ABS( a );
-    s ^= b; b = FT_ABS( b );
-    s ^= c; c = FT_ABS( c );
+    if ( a_ == 0 || b_ == c_ )
+      return a_;
 
-    if ( (FT_ULong)a + (FT_ULong)b <= 92681UL && c > 0 )
+    FT_MOVE_SIGN( a_, s );
+    FT_MOVE_SIGN( b_, s );
+    FT_MOVE_SIGN( c_, s );
+
+    a = (FT_UInt32)a_;
+    b = (FT_UInt32)b_;
+    c = (FT_UInt32)c_;
+
+    if ( c == 0 )
+      a = 0x7FFFFFFFUL;
+
+    else if ( a + b <= 131071UL )
       a = a * b / c;
 
-    else if ( (FT_Int32)c > 0 )
+    else
     {
       FT_Int64  temp;
 
 
-      ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp );
-      a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c );
-    }
-    else
-      a = 0x7FFFFFFFL;
+      ft_multo64( a, b, &temp );
 
-    return ( s < 0 ? -a : a );
+      /* last attempt to ditch long division */
+      a = temp.hi == 0 ? temp.lo / c
+                       : ft_div64by32( temp.hi, temp.lo, c );
+    }
+
+    a_ = (FT_Long)a;
+
+    return s < 0 ? -a_ : a_;
   }
 
 
   /* documentation is in freetype.h */
 
   FT_EXPORT_DEF( FT_Long )
-  FT_MulFix( FT_Long  a,
-             FT_Long  b )
+  FT_MulFix( FT_Long  a_,
+             FT_Long  b_ )
   {
 #ifdef FT_MULFIX_ASSEMBLER
 
-    return FT_MULFIX_ASSEMBLER( a, b );
+    return FT_MULFIX_ASSEMBLER( a_, b_ );
 
 #elif 0
 
@@ -707,12 +542,12 @@
      *  the leftmost bits by copying the sign bit, it might be faster.
      */
 
-    FT_Long   sa, sb;
-    FT_ULong  ua, ub;
+    FT_Long    sa, sb;
+    FT_UInt32  a, b;
 
 
-    if ( a == 0 || b == 0x10000L )
-      return a;
+    if ( a_ == 0 || b_ == 0x10000L )
+      return a_;
 
     /*
      *  This is a clever way of converting a signed number `a' into its
@@ -732,57 +567,61 @@
      *  with the value 1 rather than -1.  After that, everything else goes
      *  wrong.
      */
-    sa = ( a >> ( sizeof ( a ) * 8 - 1 ) );
-    a  = ( a ^ sa ) - sa;
-    sb = ( b >> ( sizeof ( b ) * 8 - 1 ) );
-    b  = ( b ^ sb ) - sb;
+    sa = ( a_ >> ( sizeof ( a_ ) * 8 - 1 ) );
+    a  = ( a_ ^ sa ) - sa;
+    sb = ( b_ >> ( sizeof ( b_ ) * 8 - 1 ) );
+    b  = ( b_ ^ sb ) - sb;
 
-    ua = (FT_ULong)a;
-    ub = (FT_ULong)b;
+    a = (FT_UInt32)a_;
+    b = (FT_UInt32)b_;
 
-    if ( ua <= 2048 && ub <= 1048576L )
-      ua = ( ua * ub + 0x8000U ) >> 16;
+    if ( a + ( b >> 8 ) <= 8190UL )
+      a = ( a * b + 0x8000U ) >> 16;
     else
     {
-      FT_ULong  al = ua & 0xFFFFU;
+      FT_UInt32  al = a & 0xFFFFUL;
 
 
-      ua = ( ua >> 16 ) * ub +  al * ( ub >> 16 ) +
-           ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 );
+      a = ( a >> 16 ) * b + al * ( b >> 16 ) +
+          ( ( al * ( b & 0xFFFFUL ) + 0x8000UL ) >> 16 );
     }
 
-    sa ^= sb,
-    ua  = (FT_ULong)(( ua ^ sa ) - sa);
+    sa ^= sb;
+    a   = ( a ^ sa ) - sa;
 
-    return (FT_Long)ua;
+    return (FT_Long)a;
 
 #else /* 0 */
 
-    FT_Long   s;
-    FT_ULong  ua, ub;
+    FT_Int     s = 1;
+    FT_UInt32  a, b;
 
 
-    if ( a == 0 || b == 0x10000L )
-      return a;
+    /* XXX: this function does not allow 64-bit arguments */
 
-    s  = a; a = FT_ABS( a );
-    s ^= b; b = FT_ABS( b );
+    if ( a_ == 0 || b_ == 0x10000L )
+      return a_;
 
-    ua = (FT_ULong)a;
-    ub = (FT_ULong)b;
+    FT_MOVE_SIGN( a_, s );
+    FT_MOVE_SIGN( b_, s );
 
-    if ( ua <= 2048 && ub <= 1048576L )
-      ua = ( ua * ub + 0x8000UL ) >> 16;
+    a = (FT_UInt32)a_;
+    b = (FT_UInt32)b_;
+
+    if ( a + ( b >> 8 ) <= 8190UL )
+      a = ( a * b + 0x8000UL ) >> 16;
     else
     {
-      FT_ULong  al = ua & 0xFFFFUL;
+      FT_UInt32  al = a & 0xFFFFUL;
 
 
-      ua = ( ua >> 16 ) * ub +  al * ( ub >> 16 ) +
-           ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 );
+      a = ( a >> 16 ) * b + al * ( b >> 16 ) +
+          ( ( al * ( b & 0xFFFFUL ) + 0x8000UL ) >> 16 );
     }
 
-    return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua );
+    a_ = (FT_Long)a;
+
+    return s < 0 ? -a_ : a_;
 
 #endif /* 0 */
 
@@ -792,26 +631,31 @@
   /* documentation is in freetype.h */
 
   FT_EXPORT_DEF( FT_Long )
-  FT_DivFix( FT_Long  a,
-             FT_Long  b )
+  FT_DivFix( FT_Long  a_,
+             FT_Long  b_ )
   {
-    FT_Int32   s;
-    FT_UInt32  q;
+    FT_Int     s = 1;
+    FT_UInt32  a, b, q;
+    FT_Long    q_;
 
 
     /* XXX: this function does not allow 64-bit arguments */
-    s  = (FT_Int32)a; a = FT_ABS( a );
-    s ^= (FT_Int32)b; b = FT_ABS( b );
 
-    if ( (FT_UInt32)b == 0 )
+    FT_MOVE_SIGN( a_, s );
+    FT_MOVE_SIGN( b_, s );
+
+    a = (FT_UInt32)a_;
+    b = (FT_UInt32)b_;
+
+    if ( b == 0 )
     {
       /* check for division by 0 */
-      q = (FT_UInt32)0x7FFFFFFFL;
+      q = 0x7FFFFFFFUL;
     }
-    else if ( ( a >> 16 ) == 0 )
+    else if ( a <= 65535UL - ( b >> 17 ) )
     {
       /* compute result directly */
-      q = (FT_UInt32)( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b;
+      q = ( ( a << 16 ) + ( b >> 1 ) ) / b;
     }
     else
     {
@@ -819,140 +663,22 @@
       FT_Int64  temp, temp2;
 
 
-      temp.hi  = (FT_Int32)( a >> 16 );
-      temp.lo  = (FT_UInt32)a << 16;
+      temp.hi  = a >> 16;
+      temp.lo  = a << 16;
       temp2.hi = 0;
-      temp2.lo = (FT_UInt32)( b >> 1 );
+      temp2.lo = b >> 1;
+
       FT_Add64( &temp, &temp2, &temp );
-      q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b );
+      q = ft_div64by32( temp.hi, temp.lo, b );
     }
 
-    return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
+    q_ = (FT_Long)q;
+
+    return s < 0 ? -q_ : q_;
   }
 
 
-#if 0
-
-  /* documentation is in ftcalc.h */
-
-  FT_EXPORT_DEF( void )
-  FT_MulTo64( FT_Int32   x,
-              FT_Int32   y,
-              FT_Int64  *z )
-  {
-    FT_Int32  s;
-
-
-    s  = x; x = FT_ABS( x );
-    s ^= y; y = FT_ABS( y );
-
-    ft_multo64( x, y, z );
-
-    if ( s < 0 )
-    {
-      z->lo = (FT_UInt32)-(FT_Int32)z->lo;
-      z->hi = ~z->hi + !( z->lo );
-    }
-  }
-
-
-  /* apparently, the second version of this code is not compiled correctly */
-  /* on Mac machines with the MPW C compiler..  tsk, tsk, tsk...           */
-
-#if 1
-
-  FT_EXPORT_DEF( FT_Int32 )
-  FT_Div64by32( FT_Int64*  x,
-                FT_Int32   y )
-  {
-    FT_Int32   s;
-    FT_UInt32  q, r, i, lo;
-
-
-    s  = x->hi;
-    if ( s < 0 )
-    {
-      x->lo = (FT_UInt32)-(FT_Int32)x->lo;
-      x->hi = ~x->hi + !x->lo;
-    }
-    s ^= y;  y = FT_ABS( y );
-
-    /* Shortcut */
-    if ( x->hi == 0 )
-    {
-      if ( y > 0 )
-        q = x->lo / y;
-      else
-        q = 0x7FFFFFFFL;
-
-      return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
-    }
-
-    r  = x->hi;
-    lo = x->lo;
-
-    if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */
-      return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL );
-                             /* Return Max/Min Int32 if division overflow. */
-                             /* This includes division by zero!            */
-    q = 0;
-    for ( i = 0; i < 32; i++ )
-    {
-      r <<= 1;
-      q <<= 1;
-      r  |= lo >> 31;
-
-      if ( r >= (FT_UInt32)y )
-      {
-        r -= y;
-        q |= 1;
-      }
-      lo <<= 1;
-    }
-
-    return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
-  }
-
-#else /* 0 */
-
-  FT_EXPORT_DEF( FT_Int32 )
-  FT_Div64by32( FT_Int64*  x,
-                FT_Int32   y )
-  {
-    FT_Int32   s;
-    FT_UInt32  q;
-
-
-    s  = x->hi;
-    if ( s < 0 )
-    {
-      x->lo = (FT_UInt32)-(FT_Int32)x->lo;
-      x->hi = ~x->hi + !x->lo;
-    }
-    s ^= y;  y = FT_ABS( y );
-
-    /* Shortcut */
-    if ( x->hi == 0 )
-    {
-      if ( y > 0 )
-        q = ( x->lo + ( y >> 1 ) ) / y;
-      else
-        q = 0x7FFFFFFFL;
-
-      return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
-    }
-
-    q = ft_div64by32( x->hi, x->lo, y );
-
-    return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
-  }
-
-#endif /* 0 */
-
-#endif /* 0 */
-
-
-#endif /* FT_LONG64 */
+#endif /* !FT_LONG64 */
 
 
   /* documentation is in ftglyph.h */
@@ -1075,7 +801,7 @@
     if ( x > 0 )
     {
       rem_hi = 0;
-      rem_lo = x;
+      rem_lo = (FT_UInt32)x;
       count  = 24;
       do
       {
@@ -1156,8 +882,8 @@
 
 
       /* XXX: this function does not allow 64-bit arguments */
-      ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 );
-      ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 );
+      ft_multo64( (FT_UInt32)in_x, (FT_UInt32)out_y, &z1 );
+      ft_multo64( (FT_UInt32)in_y, (FT_UInt32)out_x, &z2 );
 
       if ( z1.hi > z2.hi )
         result = +1;
@@ -1186,55 +912,40 @@
                      FT_Pos  out_x,
                      FT_Pos  out_y )
   {
-    FT_Pos  ax = in_x;
-    FT_Pos  ay = in_y;
+    FT_Pos  ax = in_x + out_x;
+    FT_Pos  ay = in_y + out_y;
 
-    FT_Pos  d_in, d_out, d_corner;
+    FT_Pos  d_in, d_out, d_hypot;
 
 
-    /* We approximate the Euclidean metric (sqrt(x^2 + y^2)) with */
-    /* the Taxicab metric (|x| + |y|), which can be computed much */
-    /* faster.  If one of the two vectors is much longer than the */
-    /* other one, the direction of the shorter vector doesn't     */
-    /* influence the result any more.                             */
-    /*                                                            */
-    /*                 corner                                     */
-    /*       x---------------------------x                        */
-    /*        \                      /                            */
-    /*         \                /                                 */
-    /*      in  \          /  out                                 */
-    /*           \    /                                           */
-    /*            o                                               */
-    /*              Point                                         */
-    /*                                                            */
+    /* The idea of this function is to compare the length of the */
+    /* hypotenuse with the `in' and `out' length.  The `corner'  */
+    /* represented by `in' and `out' is flat if the hypotenuse's */
+    /* length isn't too large.                                   */
+    /*                                                           */
+    /* This approach has the advantage that the angle between    */
+    /* `in' and `out' is not checked.  In case one of the two    */
+    /* vectors is `dominant', this is, much larger than the      */
+    /* other vector, we thus always have a flat corner.          */
+    /*                                                           */
+    /*                hypotenuse                                 */
+    /*       x---------------------------x                       */
+    /*        \                      /                           */
+    /*         \                /                                */
+    /*      in  \          /  out                                */
+    /*           \    /                                          */
+    /*            o                                              */
+    /*              Point                                        */
 
-    if ( ax < 0 )
-      ax = -ax;
-    if ( ay < 0 )
-      ay = -ay;
-    d_in = ax + ay;  /* d_in = || in || */
-
-    ax = out_x;
-    if ( ax < 0 )
-      ax = -ax;
-    ay = out_y;
-    if ( ay < 0 )
-      ay = -ay;
-    d_out = ax + ay;  /* d_out = || out || */
-
-    ax = out_x + in_x;
-    if ( ax < 0 )
-      ax = -ax;
-    ay = out_y + in_y;
-    if ( ay < 0 )
-      ay = -ay;
-    d_corner = ax + ay;  /* d_corner = || in + out || */
+    d_in    = FT_HYPOT(  in_x,  in_y );
+    d_out   = FT_HYPOT( out_x, out_y );
+    d_hypot = FT_HYPOT(    ax,    ay );
 
     /* now do a simple length comparison: */
     /*                                    */
-    /*   d_in + d_out < 17/16 d_corner    */
+    /*   d_in + d_out < 17/16 d_hypot     */
 
-    return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
+    return ( d_in + d_out - d_hypot ) < ( d_hypot >> 4 );
   }
 
 
diff --git a/src/base/ftdbgmem.c b/src/base/ftdbgmem.c
index 6fb86fe..6f20313 100644
--- a/src/base/ftdbgmem.c
+++ b/src/base/ftdbgmem.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Memory debugger (body).                                              */
 /*                                                                         */
-/*  Copyright 2001-2006, 2009, 2013 by                                     */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -35,7 +35,7 @@
 
 #include FT_CONFIG_STANDARD_LIBRARY_H
 
-  FT_BASE_DEF( const char* )  _ft_debug_file   = 0;
+  FT_BASE_DEF( const char* )  _ft_debug_file   = NULL;
   FT_BASE_DEF( long )         _ft_debug_lineno = 0;
 
   extern void
@@ -47,7 +47,7 @@
   typedef struct FT_MemTableRec_*   FT_MemTable;
 
 
-#define FT_MEM_VAL( addr )  ((FT_PtrDist)(FT_Pointer)( addr ))
+#define FT_MEM_VAL( addr )  ( (FT_PtrDist)(FT_Pointer)( addr ) )
 
   /*
    *  This structure holds statistics for a single allocation/release
@@ -76,7 +76,7 @@
 
 
   /*
-   *  We don't need a resizable array for the memory sources, because
+   *  We don't need a resizable array for the memory sources because
    *  their number is pretty limited within FreeType.
    */
 #define FT_MEM_SOURCE_BUCKETS  128
@@ -85,8 +85,8 @@
    *  This structure holds information related to a single allocated
    *  memory block.  If KEEPALIVE is defined, blocks that are freed by
    *  FreeType are never released to the system.  Instead, their `size'
-   *  field is set to -size.  This is mainly useful to detect double frees,
-   *  at the price of large memory footprint during execution.
+   *  field is set to `-size'.  This is mainly useful to detect double
+   *  frees, at the price of a large memory footprint during execution.
    */
   typedef struct  FT_MemNodeRec_
   {
@@ -111,20 +111,20 @@
    */
   typedef struct  FT_MemTableRec_
   {
-    FT_ULong         size;
-    FT_ULong         nodes;
+    FT_Long          size;
+    FT_Long          nodes;
     FT_MemNode*      buckets;
 
-    FT_ULong         alloc_total;
-    FT_ULong         alloc_current;
-    FT_ULong         alloc_max;
-    FT_ULong         alloc_count;
+    FT_Long          alloc_total;
+    FT_Long          alloc_current;
+    FT_Long          alloc_max;
+    FT_Long          alloc_count;
 
     FT_Bool          bound_total;
-    FT_ULong         alloc_total_max;
+    FT_Long          alloc_total_max;
 
     FT_Bool          bound_count;
-    FT_ULong         alloc_count_max;
+    FT_Long          alloc_count_max;
 
     FT_MemSource     sources[FT_MEM_SOURCE_BUCKETS];
 
@@ -142,14 +142,14 @@
 #define FT_MEM_SIZE_MIN  7
 #define FT_MEM_SIZE_MAX  13845163
 
-#define FT_FILENAME( x )  ((x) ? (x) : "unknown file")
+#define FT_FILENAME( x )  ( (x) ? (x) : "unknown file" )
 
 
   /*
    *  Prime numbers are ugly to handle.  It would be better to implement
    *  L-Hashing, which is 10% faster and doesn't require divisions.
    */
-  static const FT_UInt  ft_mem_primes[] =
+  static const FT_Int  ft_mem_primes[] =
   {
     7,
     11,
@@ -189,10 +189,10 @@
   };
 
 
-  static FT_ULong
-  ft_mem_closest_prime( FT_ULong  num )
+  static FT_Long
+  ft_mem_closest_prime( FT_Long  num )
   {
-    FT_UInt  i;
+    size_t  i;
 
 
     for ( i = 0;
@@ -204,7 +204,7 @@
   }
 
 
-  extern void
+  static void
   ft_mem_debug_panic( const char*  fmt,
                       ... )
   {
@@ -254,19 +254,20 @@
   static void
   ft_mem_table_resize( FT_MemTable  table )
   {
-    FT_ULong  new_size;
+    FT_Long  new_size;
 
 
     new_size = ft_mem_closest_prime( table->nodes );
     if ( new_size != table->size )
     {
       FT_MemNode*  new_buckets;
-      FT_ULong     i;
+      FT_Long      i;
 
 
       new_buckets = (FT_MemNode *)
-                      ft_mem_table_alloc( table,
-                                          new_size * sizeof ( FT_MemNode ) );
+                      ft_mem_table_alloc(
+                        table,
+                        new_size * (FT_Long)sizeof ( FT_MemNode ) );
       if ( new_buckets == NULL )
         return;
 
@@ -282,7 +283,7 @@
         while ( node )
         {
           next  = node->link;
-          hash  = FT_MEM_VAL( node->address ) % new_size;
+          hash  = FT_MEM_VAL( node->address ) % (FT_PtrDist)new_size;
           pnode = new_buckets + hash;
 
           node->link = pnode[0];
@@ -325,8 +326,9 @@
     table->free    = memory->free;
 
     table->buckets = (FT_MemNode *)
-                       memory->alloc( memory,
-                                      table->size * sizeof ( FT_MemNode ) );
+                       memory->alloc(
+                         memory,
+                         table->size * (FT_Long)sizeof ( FT_MemNode ) );
     if ( table->buckets )
       FT_ARRAY_ZERO( table->buckets, table->size );
     else
@@ -343,9 +345,9 @@
   static void
   ft_mem_table_destroy( FT_MemTable  table )
   {
-    FT_ULong  i;
-    FT_Long   leak_count = 0;
-    FT_ULong  leaks      = 0;
+    FT_Long  i;
+    FT_Long  leak_count = 0;
+    FT_Long  leaks      = 0;
 
 
     FT_DumpMemory( table->memory );
@@ -359,7 +361,7 @@
       while ( node )
       {
         next       = node->link;
-        node->link = 0;
+        node->link = NULL;
 
         if ( node->size > 0 )
         {
@@ -381,7 +383,7 @@
         ft_mem_table_free( table, node );
         node = next;
       }
-      table->buckets[i] = 0;
+      table->buckets[i] = NULL;
     }
 
     ft_mem_table_free( table, table->buckets );
@@ -430,7 +432,7 @@
 
 
     hash  = FT_MEM_VAL( address );
-    pnode = table->buckets + ( hash % table->size );
+    pnode = table->buckets + ( hash % (FT_PtrDist)table->size );
 
     for (;;)
     {
@@ -466,8 +468,8 @@
       if ( node == NULL )
         break;
 
-      if ( node->file_name == _ft_debug_file &&
-           node->line_no   == _ft_debug_lineno   )
+      if ( node->file_name == _ft_debug_file   &&
+           node->line_no   == _ft_debug_lineno )
         goto Exit;
 
       pnode = &node->link;
@@ -485,11 +487,11 @@
     node->max_blocks = 0;
     node->all_blocks = 0;
 
-    node->cur_size   = 0;
-    node->max_size   = 0;
-    node->all_size   = 0;
+    node->cur_size = 0;
+    node->max_size = 0;
+    node->all_size = 0;
 
-    node->cur_max    = 0;
+    node->cur_max = 0;
 
     node->link = NULL;
     node->hash = hash;
@@ -503,7 +505,7 @@
   static void
   ft_mem_table_set( FT_MemTable  table,
                     FT_Byte*     address,
-                    FT_ULong     size,
+                    FT_Long      size,
                     FT_Long      delta )
   {
     FT_MemNode  *pnode, node;
@@ -558,7 +560,7 @@
           source->max_blocks = source->cur_blocks;
       }
 
-      if ( size > (FT_ULong)source->cur_max )
+      if ( size > source->cur_max )
         source->cur_max = size;
 
       if ( delta != 0 )
@@ -671,7 +673,7 @@
   }
 
 
-  extern FT_Pointer
+  static FT_Pointer
   ft_mem_debug_alloc( FT_Memory  memory,
                       FT_Long    size )
   {
@@ -688,14 +690,14 @@
       return NULL;
 
     /* return NULL if this allocation would overflow the maximum heap size */
-    if ( table->bound_total                                             &&
-         table->alloc_total_max - table->alloc_current > (FT_ULong)size )
+    if ( table->bound_total                                   &&
+         table->alloc_total_max - table->alloc_current > size )
       return NULL;
 
     block = (FT_Byte *)ft_mem_table_alloc( table, size );
     if ( block )
     {
-      ft_mem_table_set( table, block, (FT_ULong)size, 0 );
+      ft_mem_table_set( table, block, size, 0 );
 
       table->alloc_count++;
     }
@@ -707,7 +709,7 @@
   }
 
 
-  extern void
+  static void
   ft_mem_debug_free( FT_Memory   memory,
                      FT_Pointer  block )
   {
@@ -731,7 +733,7 @@
   }
 
 
-  extern FT_Pointer
+  static FT_Pointer
   ft_mem_debug_realloc( FT_Memory   memory,
                         FT_Long     cur_size,
                         FT_Long     new_size,
@@ -787,21 +789,22 @@
          table->alloc_count >= table->alloc_count_max )
       return NULL;
 
-    delta = (FT_Long)( new_size - cur_size );
+    delta = new_size - cur_size;
 
     /* return NULL if this allocation would overflow the maximum heap size */
-    if ( delta > 0                                                       &&
-         table->bound_total                                              &&
-         table->alloc_current + (FT_ULong)delta > table->alloc_total_max )
+    if ( delta > 0                                             &&
+         table->bound_total                                    &&
+         table->alloc_current + delta > table->alloc_total_max )
       return NULL;
 
-    new_block = (FT_Byte *)ft_mem_table_alloc( table, new_size );
+    new_block = (FT_Pointer)ft_mem_table_alloc( table, new_size );
     if ( new_block == NULL )
       return NULL;
 
     ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta );
 
-    ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size );
+    ft_memcpy( new_block, block, cur_size < new_size ? (size_t)cur_size
+                                                     : (size_t)new_size );
 
     ft_mem_table_remove( table, (FT_Byte*)block, delta );
 
@@ -844,7 +847,7 @@
           if ( total_max > 0 )
           {
             table->bound_total     = 1;
-            table->alloc_total_max = (FT_ULong)total_max;
+            table->alloc_total_max = total_max;
           }
         }
 
@@ -857,7 +860,7 @@
           if ( total_count > 0 )
           {
             table->bound_count     = 1;
-            table->alloc_count_max = (FT_ULong)total_count;
+            table->alloc_count_max = total_count;
           }
         }
 
@@ -896,7 +899,6 @@
   }
 
 
-
   static int
   ft_mem_source_compare( const void*  p1,
                          const void*  p2 )
@@ -925,7 +927,7 @@
       FT_MemSource*  bucket = table->sources;
       FT_MemSource*  limit  = bucket + FT_MEM_SOURCE_BUCKETS;
       FT_MemSource*  sources;
-      FT_UInt        nn, count;
+      FT_Int         nn, count;
       const char*    fmt;
 
 
@@ -939,8 +941,9 @@
           count++;
       }
 
-      sources = (FT_MemSource*)ft_mem_table_alloc(
-                                 table, sizeof ( *sources ) * count );
+      sources = (FT_MemSource*)
+                  ft_mem_table_alloc(
+                    table, count * (FT_Long)sizeof ( *sources ) );
 
       count = 0;
       for ( bucket = table->sources; bucket < limit; bucket++ )
@@ -952,7 +955,10 @@
           sources[count++] = source;
       }
 
-      ft_qsort( sources, count, sizeof ( *sources ), ft_mem_source_compare );
+      ft_qsort( sources,
+                (size_t)count,
+                sizeof ( *sources ),
+                ft_mem_source_compare );
 
       printf( "FreeType Memory Dump: "
               "current=%ld max=%ld total=%ld count=%ld\n",
diff --git a/src/base/ftdebug.c b/src/base/ftdebug.c
index 39ac6ad..2cdb7c2 100644
--- a/src/base/ftdebug.c
+++ b/src/base/ftdebug.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Debugging and logging component (body).                              */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2004, 2008, 2013 by                         */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftxf86.c b/src/base/ftfntfmt.c
similarity index 67%
rename from src/base/ftxf86.c
rename to src/base/ftfntfmt.c
index a4bf767..98e7431 100644
--- a/src/base/ftxf86.c
+++ b/src/base/ftfntfmt.c
@@ -1,10 +1,10 @@
 /***************************************************************************/
 /*                                                                         */
-/*  ftxf86.c                                                               */
+/*  ftfntfmt.c                                                             */
 /*                                                                         */
-/*    FreeType utility file for X11 support (body).                        */
+/*    FreeType utility file for font formats (body).                       */
 /*                                                                         */
-/*  Copyright 2002, 2003, 2004 by                                          */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -17,12 +17,27 @@
 
 
 #include <ft2build.h>
-#include FT_XFREE86_H
+#include FT_FONT_FORMATS_H
 #include FT_INTERNAL_OBJECTS_H
-#include FT_SERVICE_XFREE86_NAME_H
+#include FT_SERVICE_FONT_FORMAT_H
 
 
-  /* documentation is in ftxf86.h */
+  /* documentation is in ftfntfmt.h */
+
+  FT_EXPORT_DEF( const char* )
+  FT_Get_Font_Format( FT_Face  face )
+  {
+    const char*  result = NULL;
+
+
+    if ( face )
+      FT_FACE_FIND_SERVICE( face, result, FONT_FORMAT );
+
+    return result;
+  }
+
+
+  /* deprecated function name; retained for ABI compatibility */
 
   FT_EXPORT_DEF( const char* )
   FT_Get_X11_Font_Format( FT_Face  face )
@@ -31,7 +46,7 @@
 
 
     if ( face )
-      FT_FACE_FIND_SERVICE( face, result, XF86_NAME );
+      FT_FACE_FIND_SERVICE( face, result, FONT_FORMAT );
 
     return result;
   }
diff --git a/src/base/ftfstype.c b/src/base/ftfstype.c
index 0bf29c7..cd3458f 100644
--- a/src/base/ftfstype.c
+++ b/src/base/ftfstype.c
@@ -1,62 +1,62 @@
-/***************************************************************************/

-/*                                                                         */

-/*  ftfstype.c                                                             */

-/*                                                                         */

-/*    FreeType utility file to access FSType data (body).                  */

-/*                                                                         */

-/*  Copyright 2008, 2009 by                                                */

-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */

-/*                                                                         */

-/*  This file is part of the FreeType project, and may only be used,       */

-/*  modified, and distributed under the terms of the FreeType project      */

-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */

-/*  this file you indicate that you have read the license and              */

-/*  understand and accept it fully.                                        */

-/*                                                                         */

-/***************************************************************************/

-

-#include <ft2build.h>

-#include FT_TYPE1_TABLES_H

-#include FT_TRUETYPE_TABLES_H

-#include FT_INTERNAL_SERVICE_H

-#include FT_SERVICE_POSTSCRIPT_INFO_H

-

-

-  /* documentation is in freetype.h */

-

-  FT_EXPORT_DEF( FT_UShort )

-  FT_Get_FSType_Flags( FT_Face  face )

-  {

-    TT_OS2*  os2;

-

-

-    /* first, try to get the fs_type directly from the font */

-    if ( face )

-    {

-      FT_Service_PsInfo  service = NULL;

-

-

-      FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );

-

-      if ( service && service->ps_get_font_extra )

-      {

-        PS_FontExtraRec  extra;

-

-

-        if ( !service->ps_get_font_extra( face, &extra ) &&

-             extra.fs_type != 0                          )

-          return extra.fs_type;

-      }

-    }

-

-    /* look at FSType before fsType for Type42 */

-

-    if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, ft_sfnt_os2 ) ) != NULL &&

-         os2->version != 0xFFFFU                                           )

-      return os2->fsType;

-

-    return 0;

-  }

-

-

-/* END */

+/***************************************************************************/
+/*                                                                         */
+/*  ftfstype.c                                                             */
+/*                                                                         */
+/*    FreeType utility file to access FSType data (body).                  */
+/*                                                                         */
+/*  Copyright 2008-2015 by                                                 */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+#include <ft2build.h>
+#include FT_TYPE1_TABLES_H
+#include FT_TRUETYPE_TABLES_H
+#include FT_INTERNAL_SERVICE_H
+#include FT_SERVICE_POSTSCRIPT_INFO_H
+
+
+  /* documentation is in freetype.h */
+
+  FT_EXPORT_DEF( FT_UShort )
+  FT_Get_FSType_Flags( FT_Face  face )
+  {
+    TT_OS2*  os2;
+
+
+    /* first, try to get the fs_type directly from the font */
+    if ( face )
+    {
+      FT_Service_PsInfo  service = NULL;
+
+
+      FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
+
+      if ( service && service->ps_get_font_extra )
+      {
+        PS_FontExtraRec  extra;
+
+
+        if ( !service->ps_get_font_extra( face, &extra ) &&
+             extra.fs_type != 0                          )
+          return extra.fs_type;
+      }
+    }
+
+    /* look at FSType before fsType for Type42 */
+
+    if ( ( os2 = (TT_OS2*)FT_Get_Sfnt_Table( face, FT_SFNT_OS2 ) ) != NULL &&
+         os2->version != 0xFFFFU                                           )
+      return os2->fsType;
+
+    return 0;
+  }
+
+
+/* END */
diff --git a/src/base/ftgasp.c b/src/base/ftgasp.c
index 8485d29..bbd257c 100644
--- a/src/base/ftgasp.c
+++ b/src/base/ftgasp.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Access of TrueType's `gasp' table (body).                            */
 /*                                                                         */
-/*  Copyright 2007 by                                                      */
+/*  Copyright 2007-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftgloadr.c b/src/base/ftgloadr.c
index 3cc5c7a..7e28638 100644
--- a/src/base/ftgloadr.c
+++ b/src/base/ftgloadr.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph loader (body).                                    */
 /*                                                                         */
-/*  Copyright 2002-2006, 2010, 2013 by                                     */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg                       */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -212,7 +212,8 @@
 
 
     /* check points & tags */
-    new_max = base->n_points + current->n_points + n_points;
+    new_max = (FT_UInt)base->n_points + (FT_UInt)current->n_points +
+              n_points;
     old_max = loader->max_points;
 
     if ( new_max > old_max )
@@ -245,7 +246,7 @@
 
     /* check contours */
     old_max = loader->max_contours;
-    new_max = base->n_contours + current->n_contours +
+    new_max = (FT_UInt)base->n_contours + (FT_UInt)current->n_contours +
               n_contours;
     if ( new_max > old_max )
     {
@@ -329,9 +330,9 @@
     FT_GlyphLoad  base;
     FT_GlyphLoad  current;
 
-    FT_UInt       n_curr_contours;
-    FT_UInt       n_base_points;
-    FT_UInt       n;
+    FT_Int        n_curr_contours;
+    FT_Int        n_base_points;
+    FT_Int        n;
 
 
     if ( !loader )
@@ -365,8 +366,8 @@
                              FT_GlyphLoader  source )
   {
     FT_Error  error;
-    FT_UInt   num_points   = source->base.outline.n_points;
-    FT_UInt   num_contours = source->base.outline.n_contours;
+    FT_UInt   num_points   = (FT_UInt)source->base.outline.n_points;
+    FT_UInt   num_contours = (FT_UInt)source->base.outline.n_contours;
 
 
     error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours );
diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c
index c62b3db..cb7fc37 100644
--- a/src/base/ftglyph.c
+++ b/src/base/ftglyph.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType convenience functions to handle glyphs (body).              */
 /*                                                                         */
-/*  Copyright 1996-2005, 2007, 2008, 2010, 2012, 2013 by                   */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -82,7 +82,7 @@
     }
     else
     {
-      FT_Bitmap_New( &glyph->bitmap );
+      FT_Bitmap_Init( &glyph->bitmap );
       error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap );
     }
 
@@ -126,9 +126,9 @@
 
 
     cbox->xMin = glyph->left << 6;
-    cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 );
+    cbox->xMax = cbox->xMin + (FT_Pos)( glyph->bitmap.width << 6 );
     cbox->yMax = glyph->top << 6;
-    cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 );
+    cbox->yMin = cbox->yMax - (FT_Pos)( glyph->bitmap.rows << 6 );
   }
 
 
@@ -173,7 +173,9 @@
     }
 
     /* allocate new outline */
-    error = FT_Outline_New( library, source->n_points, source->n_contours,
+    error = FT_Outline_New( library,
+                            (FT_UInt)source->n_points,
+                            source->n_contours,
                             &glyph->outline );
     if ( error )
       goto Exit;
@@ -205,8 +207,10 @@
     FT_Library       library = FT_GLYPH( source )->library;
 
 
-    error = FT_Outline_New( library, source->outline.n_points,
-                            source->outline.n_contours, &target->outline );
+    error = FT_Outline_New( library,
+                            (FT_UInt)source->outline.n_points,
+                            source->outline.n_contours,
+                            &target->outline );
     if ( !error )
       FT_Outline_Copy( &source->outline, &target->outline );
 
@@ -287,7 +291,7 @@
      FT_Glyph   glyph  = NULL;
 
 
-     *aglyph = 0;
+     *aglyph = NULL;
 
      if ( !FT_ALLOC( glyph, clazz->glyph_size ) )
      {
@@ -314,13 +318,13 @@
 
 
     /* check arguments */
-    if ( !target )
+    if ( !target || !source || !source->clazz )
     {
       error = FT_THROW( Invalid_Argument );
       goto Exit;
     }
 
-    *target = 0;
+    *target = NULL;
 
     if ( !source || !source->clazz )
     {
@@ -359,7 +363,7 @@
     FT_Error    error;
     FT_Glyph    glyph;
 
-    const FT_Glyph_Class*  clazz = 0;
+    const FT_Glyph_Class*  clazz = NULL;
 
 
     if ( !slot )
@@ -512,7 +516,7 @@
     FT_BitmapGlyph            bitmap = NULL;
     const FT_Glyph_Class*     clazz;
 
-    /* FT_BITMAP_GLYPH_CLASS_GET derefers `library' in PIC mode */
+    /* FT_BITMAP_GLYPH_CLASS_GET dereferences `library' in PIC mode */
     FT_Library                library;
 
 
diff --git a/src/base/ftinit.c b/src/base/ftinit.c
index 6176273..cc95e6a 100644
--- a/src/base/ftinit.c
+++ b/src/base/ftinit.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType initialization layer (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2002, 2005, 2007, 2009, 2012, 2013 by                   */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -138,7 +138,7 @@
 #include FT_CONFIG_MODULES_H
 
     FT_FREE( classes );
-    pic_container->default_module_classes = 0;
+    pic_container->default_module_classes = NULL;
   }
 
 
@@ -164,7 +164,7 @@
 
     memory = library->memory;
 
-    pic_container->default_module_classes = 0;
+    pic_container->default_module_classes = NULL;
 
     if ( FT_ALLOC( classes, sizeof ( FT_Module_Class* ) *
                               ( FT_NUM_MODULE_CLASSES + 1 ) ) )
@@ -172,8 +172,8 @@
 
     /* initialize all pointers to 0, especially the last one */
     for ( i = 0; i < FT_NUM_MODULE_CLASSES; i++ )
-      classes[i] = 0;
-    classes[FT_NUM_MODULE_CLASSES] = 0;
+      classes[i] = NULL;
+    classes[FT_NUM_MODULE_CLASSES] = NULL;
 
     i = 0;
 
@@ -235,6 +235,8 @@
     FT_Memory  memory;
 
 
+    /* check of `alibrary' delayed to `FT_New_Library' */
+
     /* First of all, allocate a new system object -- this function is part */
     /* of the system-specific component, i.e. `ftsystem.c'.                */
 
@@ -263,17 +265,19 @@
   FT_EXPORT_DEF( FT_Error )
   FT_Done_FreeType( FT_Library  library )
   {
-    if ( library )
-    {
-      FT_Memory  memory = library->memory;
+    FT_Memory  memory;
 
 
-      /* Discard the library object */
-      FT_Done_Library( library );
+    if ( !library )
+      return FT_THROW( Invalid_Library_Handle );
 
-      /* discard memory manager */
-      FT_Done_Memory( memory );
-    }
+    memory = library->memory;
+
+    /* Discard the library object */
+    FT_Done_Library( library );
+
+    /* discard memory manager */
+    FT_Done_Memory( memory );
 
     return FT_Err_Ok;
   }
diff --git a/src/base/ftlcdfil.c b/src/base/ftlcdfil.c
index 4aefb68..ff6f7e9 100644
--- a/src/base/ftlcdfil.c
+++ b/src/base/ftlcdfil.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for color filtering of subpixel bitmap glyphs (body).   */
 /*                                                                         */
-/*  Copyright 2006, 2008-2010, 2013, 2014 by                               */
+/*  Copyright 2006-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -46,6 +46,10 @@
       FT_Byte*  line = bitmap->buffer;
 
 
+      /* take care of bitmap flow */
+      if ( bitmap->pitch < 0 )
+        line -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 );
+
       /* `fir' and `pix' must be at least 32 bit wide, since the sum of */
       /* the values in `weights' can exceed 0xFF                        */
 
@@ -106,6 +110,10 @@
       FT_Int    pitch  = bitmap->pitch;
 
 
+      /* take care of bitmap flow */
+      if ( bitmap->pitch < 0 )
+        column -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 );
+
       for ( ; width > 0; width--, column++ )
       {
         FT_Byte*  col = column;
@@ -174,7 +182,7 @@
     FT_UInt  height = (FT_UInt)bitmap->rows;
     FT_Int   pitch  = bitmap->pitch;
 
-    static const int  filters[3][3] =
+    static const unsigned int  filters[3][3] =
     {
       { 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 },
       { 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 },
@@ -190,6 +198,10 @@
       FT_Byte*  line = bitmap->buffer;
 
 
+      /* take care of bitmap flow */
+      if ( bitmap->pitch < 0 )
+        line -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 );
+
       for ( ; height > 0; height--, line += pitch )
       {
         FT_UInt  xx;
@@ -229,10 +241,14 @@
       FT_Byte*  column = bitmap->buffer;
 
 
+      /* take care of bitmap flow */
+      if ( bitmap->pitch < 0 )
+        column -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 );
+
       for ( ; width > 0; width--, column++ )
       {
         FT_Byte*  col     = column;
-        FT_Byte*  col_end = col + height * pitch;
+        FT_Byte*  col_end = col + (FT_Int)height * pitch;
 
 
         for ( ; col < col_end; col += 3 * pitch )
@@ -273,7 +289,10 @@
   FT_Library_SetLcdFilterWeights( FT_Library      library,
                                   unsigned char  *weights )
   {
-    if ( !library || !weights )
+    if ( !library )
+      return FT_THROW( Invalid_Library_Handle );
+
+    if ( !weights )
       return FT_THROW( Invalid_Argument );
 
     ft_memcpy( library->lcd_weights, weights, 5 );
@@ -295,7 +314,7 @@
 
 
     if ( !library )
-      return FT_THROW( Invalid_Argument );
+      return FT_THROW( Invalid_Library_Handle );
 
     switch ( filter )
     {
diff --git a/src/base/ftmm.c b/src/base/ftmm.c
index 18ff879..7c012aa 100644
--- a/src/base/ftmm.c
+++ b/src/base/ftmm.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Multiple Master font support (body).                                 */
 /*                                                                         */
-/*  Copyright 1996-2001, 2003, 2004, 2009, 2013 by                         */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -72,6 +72,11 @@
     FT_Service_MultiMasters  service;
 
 
+    /* check of `face' delayed to `ft_face_get_mm_service' */
+
+    if ( !amaster )
+      return FT_THROW( Invalid_Argument );
+
     error = ft_face_get_mm_service( face, &service );
     if ( !error )
     {
@@ -94,6 +99,11 @@
     FT_Service_MultiMasters  service;
 
 
+    /* check of `face' delayed to `ft_face_get_mm_service' */
+
+    if ( !amaster )
+      return FT_THROW( Invalid_Argument );
+
     error = ft_face_get_mm_service( face, &service );
     if ( !error )
     {
@@ -117,6 +127,11 @@
     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 )
     {
@@ -140,6 +155,11 @@
     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 )
     {
@@ -163,6 +183,11 @@
     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 )
     {
@@ -189,6 +214,11 @@
     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 )
     {
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index cc56105..9c3332c 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType private base classes (body).                            */
 /*                                                                         */
-/*  Copyright 1996-2014 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -158,7 +158,7 @@
     FT_Stream  stream = NULL;
 
 
-    *astream = 0;
+    *astream = NULL;
 
     if ( !library )
       return FT_THROW( Invalid_Library_Handle );
@@ -178,7 +178,7 @@
       /* create a memory-based stream */
       FT_Stream_OpenMemory( stream,
                             (const FT_Byte*)args->memory_base,
-                            args->memory_size );
+                            (FT_ULong)args->memory_size );
     }
 
 #ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT
@@ -353,10 +353,10 @@
     slot->bitmap_left   = 0;
     slot->bitmap_top    = 0;
     slot->num_subglyphs = 0;
-    slot->subglyphs     = 0;
-    slot->control_data  = 0;
+    slot->subglyphs     = NULL;
+    slot->control_data  = NULL;
     slot->control_len   = 0;
-    slot->other         = 0;
+    slot->other         = NULL;
     slot->format        = FT_GLYPH_FORMAT_NONE;
 
     slot->linearHoriAdvance = 0;
@@ -387,7 +387,7 @@
       if ( FT_DRIVER_USES_OUTLINES( driver ) )
       {
         FT_GlyphLoader_Done( slot->internal->loader );
-        slot->internal->loader = 0;
+        slot->internal->loader = NULL;
       }
 
       FT_FREE( slot->internal );
@@ -408,7 +408,10 @@
     FT_GlyphSlot     slot = NULL;
 
 
-    if ( !face || !face->driver )
+    if ( !face )
+      return FT_THROW( Invalid_Face_Handle );
+
+    if ( !face->driver )
       return FT_THROW( Invalid_Argument );
 
     driver = face->driver;
@@ -435,7 +438,7 @@
         *aslot = slot;
     }
     else if ( aslot )
-      *aslot = 0;
+      *aslot = NULL;
 
 
   Exit:
@@ -508,6 +511,7 @@
       internal->transform_matrix.xy = 0;
       internal->transform_matrix.yx = 0;
       internal->transform_matrix.yy = 0x10000L;
+
       matrix = &internal->transform_matrix;
     }
     else
@@ -523,6 +527,7 @@
     {
       internal->transform_delta.x = 0;
       internal->transform_delta.y = 0;
+
       delta = &internal->transform_delta;
     }
     else
@@ -927,7 +932,7 @@
                       (FT_List_Destructor)destroy_size,
                       memory,
                       driver );
-    face->size = 0;
+    face->size = NULL;
 
     /* now discard client data */
     if ( face->generic.finalizer )
@@ -945,7 +950,7 @@
       face->stream,
       ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
 
-    face->stream = 0;
+    face->stream = NULL;
 
     /* get rid of it */
     if ( face->internal )
@@ -963,10 +968,6 @@
                       (FT_List_Destructor)destroy_face,
                       driver->root.memory,
                       driver );
-
-    /* check whether we need to drop the driver's glyph loader */
-    if ( FT_DRIVER_USES_OUTLINES( driver ) )
-      FT_GlyphLoader_Done( driver->glyph_loader );
   }
 
 
@@ -1040,14 +1041,6 @@
              ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
                cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32    ) )
         {
-#ifdef FT_MAX_CHARMAP_CACHEABLE
-          if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
-          {
-            FT_ERROR(( "find_unicode_charmap: UCS-4 cmap is found "
-                       "at too late position (%d)\n", cur - first ));
-            continue;
-          }
-#endif
           face->charmap = cur[0];
           return FT_Err_Ok;
         }
@@ -1062,14 +1055,6 @@
     {
       if ( cur[0]->encoding == FT_ENCODING_UNICODE )
       {
-#ifdef FT_MAX_CHARMAP_CACHEABLE
-        if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
-        {
-          FT_ERROR(( "find_unicode_charmap: UCS-2 cmap is found "
-                     "at too late position (%d)\n", cur - first ));
-          continue;
-        }
-#endif
         face->charmap = cur[0];
         return FT_Err_Ok;
       }
@@ -1111,17 +1096,7 @@
       if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE    &&
            cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR &&
            FT_Get_CMap_Format( cur[0] ) == 14                  )
-      {
-#ifdef FT_MAX_CHARMAP_CACHEABLE
-        if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
-        {
-          FT_ERROR(( "find_unicode_charmap: UVS cmap is found "
-                     "at too late position (%d)\n", cur - first ));
-          continue;
-        }
-#endif
         return cur[0];
-      }
     }
 
     return NULL;
@@ -1178,7 +1153,7 @@
       int  i;
 
 
-      face->internal->incremental_interface = 0;
+      face->internal->incremental_interface = NULL;
       for ( i = 0; i < num_params && !face->internal->incremental_interface;
             i++ )
         if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL )
@@ -1220,7 +1195,7 @@
         clazz->done_face( face );
       FT_FREE( internal );
       FT_FREE( face );
-      *aface = 0;
+      *aface = NULL;
     }
 
     return error;
@@ -1243,7 +1218,7 @@
     FT_Open_Args  args;
 
 
-    /* test for valid `library' and `aface' delayed to FT_Open_Face() */
+    /* test for valid `library' and `aface' delayed to `FT_Open_Face' */
     if ( !pathname )
       return FT_THROW( Invalid_Argument );
 
@@ -1269,7 +1244,7 @@
     FT_Open_Args  args;
 
 
-    /* test for valid `library' and `face' delayed to FT_Open_Face() */
+    /* test for valid `library' and `face' delayed to `FT_Open_Face' */
     if ( !file_base )
       return FT_THROW( Invalid_Argument );
 
@@ -1323,8 +1298,8 @@
     FT_FREE( stream->base );
 
     stream->size  = 0;
-    stream->base  = 0;
-    stream->close = 0;
+    stream->base  = NULL;
+    stream->close = NULL;
   }
 
 
@@ -1348,7 +1323,7 @@
     if ( !base )
       return FT_THROW( Invalid_Argument );
 
-    *astream = 0;
+    *astream = NULL;
     memory = library->memory;
     if ( FT_NEW( stream ) )
       goto Exit;
@@ -1512,7 +1487,7 @@
     FT_Error   error;
     FT_Memory  memory = library->memory;
     FT_ULong   offset, length;
-    FT_Long    pos;
+    FT_ULong   pos;
     FT_Bool    is_sfnt_cid;
     FT_Byte*   sfnt_ps = NULL;
 
@@ -1520,7 +1495,7 @@
     FT_UNUSED( params );
 
 
-    pos = FT_Stream_Pos( stream );
+    pos = FT_STREAM_POS();
 
     error = ft_lookup_PS_in_sfnt_stream( stream,
                                          face_index,
@@ -1583,9 +1558,9 @@
     FT_Memory  memory = library->memory;
     FT_Byte*   pfb_data = NULL;
     int        i, type, flags;
-    FT_Long    len;
-    FT_Long    pfb_len, pfb_pos, pfb_lenpos;
-    FT_Long    rlen, temp;
+    FT_ULong   len;
+    FT_ULong   pfb_len, pfb_pos, pfb_lenpos;
+    FT_ULong   rlen, temp;
 
 
     if ( face_index == -1 )
@@ -1598,14 +1573,37 @@
     pfb_len = 0;
     for ( i = 0; i < resource_cnt; ++i )
     {
-      error = FT_Stream_Seek( stream, offsets[i] );
+      error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] );
       if ( error )
         goto Exit;
-      if ( FT_READ_LONG( temp ) )
+      if ( FT_READ_ULONG( temp ) )
         goto Exit;
+
+      /* FT2 allocator takes signed long buffer length,
+       * too large value causing overflow should be checked
+       */
+      FT_TRACE4(( "                 POST fragment #%d: length=0x%08x\n",
+                  i, temp));
+      if ( 0x7FFFFFFFUL < temp || pfb_len + temp + 6 < pfb_len )
+      {
+        FT_TRACE2(( "             too long fragment length makes"
+                    " pfb_len confused: temp=0x%08x\n", temp ));
+        error = FT_THROW( Invalid_Offset );
+        goto Exit;
+      }
+
       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(( "             too long fragment length makes"
+                  " 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;
 
@@ -1622,19 +1620,33 @@
     type = 1;
     for ( i = 0; i < resource_cnt; ++i )
     {
-      error = FT_Stream_Seek( stream, offsets[i] );
+      error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] );
       if ( error )
         goto Exit2;
-      if ( FT_READ_LONG( rlen ) )
-        goto Exit;
+      if ( FT_READ_ULONG( rlen ) )
+        goto Exit2;
+
+      /* FT2 allocator takes signed long buffer length,
+       * too large fragment length causing overflow should be checked
+       */
+      if ( 0x7FFFFFFFUL < rlen )
+      {
+        error = FT_THROW( Invalid_Offset );
+        goto Exit2;
+      }
+
       if ( FT_READ_USHORT( flags ) )
-        goto Exit;
+        goto Exit2;
       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() */
       if ( ( flags >> 8 ) == 0 )        /* Comment, should not be loaded */
+      {
+        FT_TRACE3(( "    Skip POST fragment #%d because it is a comment\n", i ));
         continue;
+      }
 
       /* the flags are part of the resource, so rlen >= 2.  */
       /* but some fonts declare rlen = 0 for empty fragment */
@@ -1647,6 +1659,8 @@
         len += rlen;
       else
       {
+        FT_TRACE3(( "    Write POST fragment #%d header (4-byte) to buffer"
+                    " 0x%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 );
@@ -1657,6 +1671,8 @@
         if ( ( flags >> 8 ) == 5 )      /* End of font mark */
           break;
 
+        FT_TRACE3(( "    Write POST fragment #%d header (6-byte) to buffer"
+                    " 0x%p + 0x%08x\n", i, pfb_data, pfb_pos ));
         if ( pfb_pos + 6 > pfb_len + 2 )
           goto Exit2;
         pfb_data[pfb_pos++] = 0x80;
@@ -1672,16 +1688,18 @@
         pfb_data[pfb_pos++] = 0;
       }
 
-      error = FT_ERR( Cannot_Open_Resource );
       if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len )
         goto Exit2;
 
+      FT_TRACE3(( "    Load POST fragment #%d (%d byte) to buffer"
+                  " 0x%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;
@@ -1702,6 +1720,13 @@
                                   aface );
 
   Exit2:
+    if ( error == FT_ERR( Array_Too_Large ) )
+      FT_TRACE2(( "  Abort due to too-short buffer to store"
+                  " all POST fragments\n" ));
+    else if ( error == FT_ERR( 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 );
 
   Exit:
@@ -1725,7 +1750,7 @@
     FT_Memory  memory = library->memory;
     FT_Byte*   sfnt_data = NULL;
     FT_Error   error;
-    FT_Long    flag_offset;
+    FT_ULong   flag_offset;
     FT_Long    rlen;
     int        is_cff;
     FT_Long    face_index_in_resource = 0;
@@ -1736,7 +1761,7 @@
     if ( face_index >= resource_cnt )
       return FT_THROW( Cannot_Open_Resource );
 
-    flag_offset = offsets[face_index];
+    flag_offset = (FT_ULong)offsets[face_index];
     error = FT_Stream_Seek( stream, flag_offset );
     if ( error )
       goto Exit;
@@ -1758,16 +1783,16 @@
     if ( FT_Stream_Seek( stream, flag_offset + 4 ) )
       goto Exit;
 
-    if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) )
+    if ( FT_ALLOC( sfnt_data, rlen ) )
       return error;
-    error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen );
+    error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, (FT_ULong)rlen );
     if ( error )
       goto Exit;
 
     is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
     error = open_face_from_buffer( library,
                                    sfnt_data,
-                                   rlen,
+                                   (FT_ULong)rlen,
                                    face_index_in_resource,
                                    is_cff ? "cff" : "truetype",
                                    aface );
@@ -1881,7 +1906,7 @@
     rlen = ( header[0x57] << 24 ) |
            ( header[0x58] << 16 ) |
            ( header[0x59] <<  8 ) |
-             header[0x5a];
+             header[0x5A];
 #endif /* 0 */
     offset = 128 + ( ( dlen + 127 ) & ~127 );
 
@@ -1905,7 +1930,7 @@
 
     FT_Memory  memory = library->memory;
     FT_Error   error  = FT_ERR( Unknown_File_Format );
-    int        i;
+    FT_UInt    i;
 
     char *     file_names[FT_RACCESS_N_RULES];
     FT_Long    offsets[FT_RACCESS_N_RULES];
@@ -1913,7 +1938,7 @@
     FT_Bool    is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */
 
     FT_Open_Args  args2;
-    FT_Stream     stream2 = 0;
+    FT_Stream     stream2 = NULL;
 
 
     FT_Raccess_Guess( library, stream,
@@ -2049,8 +2074,7 @@
     FT_Module*   limit;
 
 
-    /* test for valid `library' delayed to */
-    /* FT_Stream_New()                     */
+    /* test for valid `library' delayed to `FT_Stream_New' */
 
     if ( ( !aface && face_index >= 0 ) || !args )
       return FT_THROW( Invalid_Argument );
@@ -2075,7 +2099,7 @@
       if ( FT_MODULE_IS_DRIVER( driver ) )
       {
         FT_Int         num_params = 0;
-        FT_Parameter*  params     = 0;
+        FT_Parameter*  params     = NULL;
 
 
         if ( args->flags & FT_OPEN_PARAMS )
@@ -2109,7 +2133,7 @@
         if ( FT_MODULE_IS_DRIVER( cur[0] ) )
         {
           FT_Int         num_params = 0;
-          FT_Parameter*  params     = 0;
+          FT_Parameter*  params     = NULL;
 
 
           driver = FT_DRIVER( cur[0] );
@@ -2297,7 +2321,7 @@
     FT_Open_Args  open;
 
 
-    /* test for valid `face' delayed to FT_Attach_Stream() */
+    /* test for valid `face' delayed to `FT_Attach_Stream' */
 
     if ( !filepathname )
       return FT_THROW( Invalid_Argument );
@@ -2323,7 +2347,7 @@
     FT_Driver_Class  clazz;
 
 
-    /* test for valid `parameters' delayed to FT_Stream_New() */
+    /* test for valid `parameters' delayed to `FT_Stream_New' */
 
     if ( !face )
       return FT_THROW( Invalid_Face_Handle );
@@ -2359,6 +2383,9 @@
   FT_EXPORT_DEF( FT_Error )
   FT_Reference_Face( FT_Face  face )
   {
+    if ( !face )
+      return FT_THROW( Invalid_Face_Handle );
+
     face->internal->refcount++;
 
     return FT_Err_Ok;
@@ -2417,20 +2444,20 @@
     FT_Driver        driver;
     FT_Driver_Class  clazz;
 
-    FT_Size          size = 0;
-    FT_ListNode      node = 0;
+    FT_Size          size = NULL;
+    FT_ListNode      node = NULL;
 
 
     if ( !face )
       return FT_THROW( Invalid_Face_Handle );
 
     if ( !asize )
-      return FT_THROW( Invalid_Size_Handle );
+      return FT_THROW( Invalid_Argument );
 
     if ( !face->driver )
       return FT_THROW( Invalid_Driver_Handle );
 
-    *asize = 0;
+    *asize = NULL;
 
     driver = face->driver;
     clazz  = driver->clazz;
@@ -2443,7 +2470,7 @@
     size->face = face;
 
     /* for now, do not use any internal fields in size objects */
-    size->internal = 0;
+    size->internal = NULL;
 
     if ( clazz->init_size )
       error = clazz->init_size( size );
@@ -2501,7 +2528,7 @@
 
       if ( face->size == size )
       {
-        face->size = 0;
+        face->size = NULL;
         if ( face->sizes_list.head )
           face->size = (FT_Size)(face->sizes_list.head->data);
       }
@@ -2934,6 +2961,8 @@
     FT_Size_RequestRec  req;
 
 
+    /* check of `face' delayed to `FT_Request_Size' */
+
     if ( !char_width )
       char_width = char_height;
     else if ( !char_height )
@@ -2972,6 +3001,8 @@
     FT_Size_RequestRec  req;
 
 
+    /* check of `face' delayed to `FT_Request_Size' */
+
     if ( pixel_width == 0 )
       pixel_width = pixel_height;
     else if ( pixel_height == 0 )
@@ -2983,14 +3014,14 @@
       pixel_height = 1;
 
     /* use `>=' to avoid potential compiler warning on 16bit platforms */
-    if ( pixel_width  >= 0xFFFFU )
-      pixel_width  = 0xFFFFU;
+    if ( pixel_width >= 0xFFFFU )
+      pixel_width = 0xFFFFU;
     if ( pixel_height >= 0xFFFFU )
       pixel_height = 0xFFFFU;
 
     req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;
-    req.width          = pixel_width << 6;
-    req.height         = pixel_height << 6;
+    req.width          = (FT_Long)( pixel_width << 6 );
+    req.height         = (FT_Long)( pixel_height << 6 );
     req.horiResolution = 0;
     req.vertResolution = 0;
 
@@ -3122,15 +3153,6 @@
     {
       if ( cur[0]->encoding == encoding )
       {
-#ifdef FT_MAX_CHARMAP_CACHEABLE
-        if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE )
-        {
-          FT_ERROR(( "FT_Select_Charmap: requested charmap is found (%d), "
-                     "but in too late position to cache\n",
-                     cur - face->charmaps ));
-          continue;
-        }
-#endif
         face->charmap = cur[0];
         return 0;
       }
@@ -3154,8 +3176,9 @@
       return FT_THROW( Invalid_Face_Handle );
 
     cur = face->charmaps;
-    if ( !cur )
+    if ( !cur || !charmap )
       return FT_THROW( Invalid_CharMap_Handle );
+
     if ( FT_Get_CMap_Format( charmap ) == 14 )
       return FT_THROW( Invalid_Argument );
 
@@ -3165,19 +3188,11 @@
     {
       if ( cur[0] == charmap )
       {
-#ifdef FT_MAX_CHARMAP_CACHEABLE
-        if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE )
-        {
-          FT_ERROR(( "FT_Set_Charmap: requested charmap is found (%d), "
-                     "but in too late position to cache\n",
-                     cur - face->charmaps ));
-          continue;
-        }
-#endif
         face->charmap = cur[0];
-        return 0;
+        return FT_Err_Ok;
       }
     }
+
     return FT_THROW( Invalid_Argument );
   }
 
@@ -3199,15 +3214,6 @@
 
     FT_ASSERT( i < charmap->face->num_charmaps );
 
-#ifdef FT_MAX_CHARMAP_CACHEABLE
-    if ( i > FT_MAX_CHARMAP_CACHEABLE )
-    {
-      FT_ERROR(( "FT_Get_Charmap_Index: requested charmap is found (%d), "
-                 "but in too late position to cache\n",
-                 i ));
-      return -i;
-    }
-#endif
     return i;
   }
 
@@ -3418,8 +3424,9 @@
     FT_UInt  result = 0;
 
 
-    if ( face && face->charmap &&
-        face->charmap->encoding == FT_ENCODING_UNICODE )
+    if ( face                                           &&
+         face->charmap                                  &&
+         face->charmap->encoding == FT_ENCODING_UNICODE )
     {
       FT_CharMap  charmap = find_variant_selector_charmap( face );
       FT_CMap     ucmap = FT_CMAP( face->charmap );
@@ -3597,7 +3604,9 @@
     FT_UInt  result = 0;
 
 
-    if ( face && FT_HAS_GLYPH_NAMES( face ) )
+    if ( face                       &&
+         FT_HAS_GLYPH_NAMES( face ) &&
+         glyph_name                 )
     {
       FT_Service_GlyphDict  service;
 
@@ -3622,27 +3631,30 @@
                      FT_Pointer  buffer,
                      FT_UInt     buffer_max )
   {
-    FT_Error  error = FT_ERR( Invalid_Argument );
+    FT_Error              error;
+    FT_Service_GlyphDict  service;
 
 
+    if ( !face )
+      return FT_THROW( Invalid_Face_Handle );
+
+    if ( !buffer || buffer_max == 0 )
+      return FT_THROW( Invalid_Argument );
+
     /* clean up buffer */
-    if ( buffer && buffer_max > 0 )
-      ((FT_Byte*)buffer)[0] = 0;
+    ((FT_Byte*)buffer)[0] = '\0';
 
-    if ( face                                     &&
-         (FT_Long)glyph_index <= face->num_glyphs &&
-         FT_HAS_GLYPH_NAMES( face )               )
-    {
-      FT_Service_GlyphDict  service;
+    if ( (FT_Long)glyph_index >= face->num_glyphs )
+      return FT_THROW( Invalid_Glyph_Index );
 
+    if ( !FT_HAS_GLYPH_NAMES( face ) )
+      return FT_THROW( Invalid_Argument );
 
-      FT_FACE_LOOKUP_SERVICE( face,
-                              service,
-                              GLYPH_DICT );
-
-      if ( service && service->get_name )
-        error = service->get_name( face, glyph_index, buffer, buffer_max );
-    }
+    FT_FACE_LOOKUP_SERVICE( face, service, GLYPH_DICT );
+    if ( service && service->get_name )
+      error = service->get_name( face, glyph_index, buffer, buffer_max );
+    else
+      error = FT_THROW( Invalid_Argument );
 
     return error;
   }
@@ -3683,7 +3695,7 @@
   FT_Get_Sfnt_Table( FT_Face      face,
                      FT_Sfnt_Tag  tag )
   {
-    void*                  table = 0;
+    void*                  table = NULL;
     FT_Service_SFNT_Table  service;
 
 
@@ -3733,6 +3745,8 @@
     FT_ULong               offset;
 
 
+    /* test for valid `length' delayed to `service->table_info' */
+
     if ( !face || !FT_IS_SFNT( face ) )
       return FT_THROW( Invalid_Face_Handle );
 
@@ -3800,12 +3814,12 @@
     FT_Face  face;
 
 
-    if ( size == NULL )
-      return FT_THROW( Invalid_Argument );
+    if ( !size )
+      return FT_THROW( Invalid_Size_Handle );
 
     face = size->face;
-    if ( face == NULL || face->driver == NULL )
-      return FT_THROW( Invalid_Argument );
+    if ( !face || !face->driver )
+      return FT_THROW( Invalid_Face_Handle );
 
     /* we don't need anything more complex than that; all size objects */
     /* are already listed by the face                                  */
@@ -3834,7 +3848,7 @@
                       FT_ListNode*     node )
   {
     FT_ListNode  cur;
-    FT_Renderer  result = 0;
+    FT_Renderer  result = NULL;
 
 
     if ( !library )
@@ -3846,7 +3860,7 @@
     {
       if ( *node )
         cur = (*node)->next;
-      *node = 0;
+      *node = NULL;
     }
 
     while ( cur )
@@ -3984,7 +3998,7 @@
   FT_Get_Renderer( FT_Library       library,
                    FT_Glyph_Format  format )
   {
-    /* test for valid `library' delayed to FT_Lookup_Renderer() */
+    /* test for valid `library' delayed to `FT_Lookup_Renderer' */
 
     return FT_Lookup_Renderer( library, format, 0 );
   }
@@ -4001,12 +4015,26 @@
     FT_ListNode  node;
     FT_Error     error = FT_Err_Ok;
 
+    FT_Renderer_SetModeFunc  set_mode;
+
 
     if ( !library )
-      return FT_THROW( Invalid_Library_Handle );
+    {
+      error = FT_THROW( Invalid_Library_Handle );
+      goto Exit;
+    }
 
     if ( !renderer )
-      return FT_THROW( Invalid_Argument );
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    if ( num_params > 0 && !parameters )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
 
     node = FT_List_Find( &library->renderers, renderer );
     if ( !node )
@@ -4020,18 +4048,14 @@
     if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE )
       library->cur_renderer = renderer;
 
-    if ( num_params > 0 )
+    set_mode = renderer->clazz->set_mode;
+
+    for ( ; num_params > 0; num_params-- )
     {
-      FT_Renderer_SetModeFunc  set_mode = renderer->clazz->set_mode;
-
-
-      for ( ; num_params > 0; num_params-- )
-      {
-        error = set_mode( renderer, parameters->tag, parameters->data );
-        if ( error )
-          break;
-        parameters++;
-      }
+      error = set_mode( renderer, parameters->tag, parameters->data );
+      if ( error )
+        break;
+      parameters++;
     }
 
   Exit:
@@ -4056,8 +4080,7 @@
 
     default:
       {
-        FT_ListNode  node   = 0;
-        FT_Bool      update = 0;
+        FT_ListNode  node = NULL;
 
 
         /* small shortcut for the very common case */
@@ -4084,13 +4107,7 @@
           /* now, look for another renderer that supports the same */
           /* format.                                               */
           renderer = FT_Lookup_Renderer( library, slot->format, &node );
-          update   = 1;
         }
-
-        /* if we changed the current renderer for the glyph image format */
-        /* we need to select it as the next current one                  */
-        if ( !error && update && renderer )
-          FT_Set_Renderer( library, renderer, 0, 0 );
       }
     }
 
@@ -4100,28 +4117,32 @@
 #define FT_COMPONENT  trace_bitmap
 
     /* we convert to a single bitmap format for computing the checksum */
+    if ( !error )
     {
       FT_Bitmap  bitmap;
       FT_Error   err;
 
 
-      FT_Bitmap_New( &bitmap );
+      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 )
       {
         MD5_CTX        ctx;
         unsigned char  md5[16];
         int            i;
+        unsigned int   rows  = bitmap.rows;
+        unsigned int   pitch = (unsigned int)bitmap.pitch;
 
 
-        MD5_Init( &ctx);
-        MD5_Update( &ctx, bitmap.buffer, bitmap.rows * bitmap.pitch );
+        MD5_Init( &ctx );
+        MD5_Update( &ctx, bitmap.buffer, rows * pitch );
         MD5_Final( md5, &ctx );
 
         FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n"
                     "  ",
-                    bitmap.rows, bitmap.pitch ));
+                    rows, pitch ));
         for ( i = 0; i < 16; i++ )
           FT_TRACE3(( "%02X", md5[i] ));
         FT_TRACE3(( "\n" ));
@@ -4194,7 +4215,7 @@
 
 
     if ( library && library->auto_hinter == module )
-      library->auto_hinter = 0;
+      library->auto_hinter = NULL;
 
     /* if the module is a renderer */
     if ( FT_MODULE_IS_RENDERER( module ) )
@@ -4290,17 +4311,10 @@
     /* if the module is a font driver */
     if ( FT_MODULE_IS_DRIVER( module ) )
     {
-      /* allocate glyph loader if needed */
       FT_Driver  driver = FT_DRIVER( module );
 
 
       driver->clazz = (FT_Driver_Class)module->clazz;
-      if ( FT_DRIVER_USES_OUTLINES( driver ) )
-      {
-        error = FT_GlyphLoader_New( memory, &driver->glyph_loader );
-        if ( error )
-          goto Fail;
-      }
     }
 
     if ( clazz->module_init )
@@ -4317,15 +4331,6 @@
     return error;
 
   Fail:
-    if ( FT_MODULE_IS_DRIVER( module ) )
-    {
-      FT_Driver  driver = FT_DRIVER( module );
-
-
-      if ( FT_DRIVER_USES_OUTLINES( driver ) )
-        FT_GlyphLoader_Done( driver->glyph_loader );
-    }
-
     if ( FT_MODULE_IS_RENDERER( module ) )
     {
       FT_Renderer  renderer = FT_RENDERER( module );
@@ -4348,7 +4353,7 @@
   FT_Get_Module( FT_Library   library,
                  const char*  module_name )
   {
-    FT_Module   result = 0;
+    FT_Module   result = NULL;
     FT_Module*  cur;
     FT_Module*  limit;
 
@@ -4460,7 +4465,7 @@
             cur[0] = cur[1];
             cur++;
           }
-          limit[0] = 0;
+          limit[0] = NULL;
 
           /* destroy the module */
           Destroy_Module( module );
@@ -4603,6 +4608,9 @@
   FT_EXPORT_DEF( FT_Error )
   FT_Reference_Library( FT_Library  library )
   {
+    if ( !library )
+      return FT_THROW( Invalid_Library_Handle );
+
     library->refcount++;
 
     return FT_Err_Ok;
@@ -4619,7 +4627,7 @@
     FT_Error    error;
 
 
-    if ( !memory )
+    if ( !memory || !alibrary )
       return FT_THROW( Invalid_Argument );
 
 #ifdef FT_DEBUG_LEVEL_ERROR
@@ -4640,12 +4648,9 @@
       goto Fail;
 #endif
 
-    /* allocate the render pool */
-    library->raster_pool_size = FT_RENDER_POOL_SIZE;
-#if FT_RENDER_POOL_SIZE > 0
-    if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
-      goto Fail;
-#endif
+    /* we don't use raster_pool anymore. */
+    library->raster_pool_size = 0;
+    library->raster_pool      = NULL;
 
     library->version_major = FREETYPE_MAJOR;
     library->version_minor = FREETYPE_MINOR;
@@ -4658,8 +4663,8 @@
 
     return FT_Err_Ok;
 
-  Fail:
 #ifdef FT_CONFIG_OPTION_PIC
+  Fail:
     ft_pic_container_destroy( library );
 #endif
     FT_FREE( library );
@@ -4788,16 +4793,12 @@
         if ( module )
         {
           Destroy_Module( module );
-          library->modules[n] = 0;
+          library->modules[n] = NULL;
         }
       }
     }
 #endif
 
-    /* Destroy raster objects */
-    FT_FREE( library->raster_pool );
-    library->raster_pool_size = 0;
-
 #ifdef FT_CONFIG_OPTION_PIC
     /* Destroy pic container contents */
     ft_pic_container_destroy( library );
diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
index 4a39dcd..d821c49 100644
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType outline management (body).                                  */
 /*                                                                         */
-/*  Copyright 1996-2008, 2010, 2012-2014 by                                */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -73,7 +73,10 @@
     FT_Pos   delta;
 
 
-    if ( !outline || !func_interface )
+    if ( !outline )
+      return FT_THROW( Invalid_Outline );
+
+    if ( !func_interface )
       return FT_THROW( Invalid_Argument );
 
     shift = func_interface->shift;
@@ -276,7 +279,7 @@
       if ( error )
         goto Exit;
 
-      first = last + 1;
+      first = (FT_UInt)last + 1;
     }
 
     FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
@@ -317,7 +320,7 @@
          FT_NEW_ARRAY( anoutline->contours, numContours ) )
       goto Fail;
 
-    anoutline->n_points    = (FT_UShort)numPoints;
+    anoutline->n_points    = (FT_Short)numPoints;
     anoutline->n_contours  = (FT_Short)numContours;
     anoutline->flags      |= FT_OUTLINE_OWNER;
 
@@ -362,7 +365,7 @@
 
       /* empty glyph? */
       if ( n_points == 0 && n_contours == 0 )
-        return 0;
+        return FT_Err_Ok;
 
       /* check point and contour counts */
       if ( n_points <= 0 || n_contours <= 0 )
@@ -384,7 +387,7 @@
         goto Bad;
 
       /* XXX: check the tags array */
-      return 0;
+      return FT_Err_Ok;
     }
 
   Bad:
@@ -401,8 +404,10 @@
     FT_Int  is_owner;
 
 
-    if ( !source            || !target            ||
-         source->n_points   != target->n_points   ||
+    if ( !source || !target )
+      return FT_THROW( Invalid_Outline );
+
+    if ( source->n_points   != target->n_points   ||
          source->n_contours != target->n_contours )
       return FT_THROW( Invalid_Argument );
 
@@ -430,20 +435,21 @@
   FT_Outline_Done_Internal( FT_Memory    memory,
                             FT_Outline*  outline )
   {
-    if ( memory && outline )
-    {
-      if ( outline->flags & FT_OUTLINE_OWNER )
-      {
-        FT_FREE( outline->points   );
-        FT_FREE( outline->tags     );
-        FT_FREE( outline->contours );
-      }
-      *outline = null_outline;
+    if ( !outline )
+      return FT_THROW( Invalid_Outline );
 
-      return FT_Err_Ok;
-    }
-    else
+    if ( !memory )
       return FT_THROW( Invalid_Argument );
+
+    if ( outline->flags & FT_OUTLINE_OWNER )
+    {
+      FT_FREE( outline->points   );
+      FT_FREE( outline->tags     );
+      FT_FREE( outline->contours );
+    }
+    *outline = null_outline;
+
+    return FT_Err_Ok;
   }
 
 
@@ -606,7 +612,6 @@
                      FT_Raster_Params*  params )
   {
     FT_Error     error;
-    FT_Bool      update = FALSE;
     FT_Renderer  renderer;
     FT_ListNode  node;
 
@@ -614,7 +619,10 @@
     if ( !library )
       return FT_THROW( Invalid_Library_Handle );
 
-    if ( !outline || !params )
+    if ( !outline )
+      return FT_THROW( Invalid_Outline );
+
+    if ( !params )
       return FT_THROW( Invalid_Argument );
 
     renderer = library->cur_renderer;
@@ -637,14 +645,8 @@
       /* format                                                */
       renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE,
                                      &node );
-      update   = TRUE;
     }
 
-    /* if we changed the current renderer for the glyph image format */
-    /* we need to select it as the next current one                  */
-    if ( !error && update && renderer )
-      FT_Set_Renderer( library, renderer, 0, 0 );
-
     return error;
   }
 
@@ -662,7 +664,7 @@
     if ( !abitmap )
       return FT_THROW( Invalid_Argument );
 
-    /* other checks are delayed to FT_Outline_Render() */
+    /* other checks are delayed to `FT_Outline_Render' */
 
     params.target = abitmap;
     params.flags  = 0;
@@ -911,7 +913,7 @@
 
 
     if ( !outline )
-      return FT_THROW( Invalid_Argument );
+      return FT_THROW( Invalid_Outline );
 
     xstrength /= 2;
     ystrength /= 2;
@@ -993,13 +995,13 @@
           l = FT_MIN( l_in, l_out );
 
           /* non-strict inequalities avoid divide-by-zero when q == l == 0 */
-          if ( FT_MulFix( xstrength, q ) <= FT_MulFix( d, l ) )
+          if ( FT_MulFix( xstrength, q ) <= FT_MulFix( l, d ) )
             shift.x = FT_MulDiv( shift.x, xstrength, d );
           else
             shift.x = FT_MulDiv( shift.x, l, q );
 
 
-          if ( FT_MulFix( ystrength, q ) <= FT_MulFix( d, l ) )
+          if ( FT_MulFix( ystrength, q ) <= FT_MulFix( l, d ) )
             shift.y = FT_MulDiv( shift.y, ystrength, d );
           else
             shift.y = FT_MulDiv( shift.y, l, q );
@@ -1041,14 +1043,19 @@
     /* We use the nonzero winding rule to find the orientation.       */
     /* Since glyph outlines behave much more `regular' than arbitrary */
     /* cubic or quadratic curves, this test deals with the polygon    */
-    /* only which is spanned up by the control points.                */
+    /* only that is spanned up by the control points.                 */
 
     FT_Outline_Get_CBox( outline, &cbox );
 
-    xshift = FT_MSB( FT_ABS( cbox.xMax ) | FT_ABS( cbox.xMin ) ) - 14;
+    /* Handle collapsed outlines to avoid undefined FT_MSB. */
+    if ( cbox.xMin == cbox.xMax || cbox.yMin == cbox.yMax )
+      return FT_ORIENTATION_NONE;
+
+    xshift = FT_MSB( (FT_UInt32)( FT_ABS( cbox.xMax ) |
+                                  FT_ABS( cbox.xMin ) ) ) - 14;
     xshift = FT_MAX( xshift, 0 );
 
-    yshift = FT_MSB( cbox.yMax - cbox.yMin ) - 14;
+    yshift = FT_MSB( (FT_UInt32)( cbox.yMax - cbox.yMin ) ) - 14;
     yshift = FT_MAX( yshift, 0 );
 
     points = outline->points;
diff --git a/src/base/ftpatent.c b/src/base/ftpatent.c
index 82b42f0..bf2b085 100644
--- a/src/base/ftpatent.c
+++ b/src/base/ftpatent.c
@@ -5,7 +5,8 @@
 /*    FreeType API for checking patented TrueType bytecode instructions    */
 /*    (body).                                                              */
 /*                                                                         */
-/*  Copyright 2007, 2008, 2010 by David Turner.                            */
+/*  Copyright 2007-2015 by                                                 */
+/*  David Turner.                                                          */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
 /*  modified, and distributed under the terms of the FreeType project      */
diff --git a/src/base/ftpic.c b/src/base/ftpic.c
index 9bd92f7..6c4b1cd 100644
--- a/src/base/ftpic.c
+++ b/src/base/ftpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services (body).              */
 /*                                                                         */
-/*  Copyright 2009, 2013 by                                                */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftrfork.c b/src/base/ftrfork.c
index 5352970..82d54f8 100644
--- a/src/base/ftrfork.c
+++ b/src/base/ftrfork.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Embedded resource forks accessor (body).                             */
 /*                                                                         */
-/*  Copyright 2004-2010, 2013, 2014 by                                     */
+/*  Copyright 2004-2015 by                                                 */
 /*  Masatake YAMATO and Redhat K.K.                                        */
 /*                                                                         */
 /*  FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are     */
@@ -63,7 +63,7 @@
     FT_UNUSED( library );
 
 
-    error = FT_Stream_Seek( stream, rfork_offset );
+    error = FT_Stream_Seek( stream, (FT_ULong)rfork_offset );
     if ( error )
       return error;
 
@@ -89,7 +89,7 @@
     if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset )
       return FT_THROW( Unknown_File_Format );
 
-    error = FT_Stream_Seek( stream, map_pos );
+    error = FT_Stream_Seek( stream, (FT_ULong)map_pos );
     if ( error )
       return error;
 
@@ -124,7 +124,7 @@
     if ( type_list == -1 )
       return FT_THROW( Unknown_File_Format );
 
-    error = FT_Stream_Seek( stream, map_pos + type_list );
+    error = FT_Stream_Seek( stream, (FT_ULong)( map_pos + type_list ) );
     if ( error )
       return error;
 
@@ -166,7 +166,7 @@
 
 
     FT_TRACE3(( "\n" ));
-    error = FT_Stream_Seek( stream, map_offset );
+    error = FT_Stream_Seek( stream, (FT_ULong)map_offset );
     if ( error )
       return error;
 
@@ -182,10 +182,10 @@
         return error;
 
       FT_TRACE2(( "Resource tags: %c%c%c%c\n",
-                  (char)( 0xff & ( tag_internal >> 24 ) ),
-                  (char)( 0xff & ( tag_internal >> 16 ) ),
-                  (char)( 0xff & ( tag_internal >>  8 ) ),
-                  (char)( 0xff & ( tag_internal >>  0 ) ) ));
+                  (char)( 0xFF & ( tag_internal >> 24 ) ),
+                  (char)( 0xFF & ( tag_internal >> 16 ) ),
+                  (char)( 0xFF & ( tag_internal >>  8 ) ),
+                  (char)( 0xFF & ( tag_internal >>  0 ) ) ));
       FT_TRACE3(( "             : subcount=%d, suboffset=0x%04x\n",
                   subcnt, rpos ));
 
@@ -194,7 +194,7 @@
         *count = subcnt + 1;
         rpos  += map_offset;
 
-        error = FT_Stream_Seek( stream, rpos );
+        error = FT_Stream_Seek( stream, (FT_ULong)rpos );
         if ( error )
           return error;
 
@@ -220,7 +220,7 @@
 
         if (sort_by_res_id)
         {
-          ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ),
+          ft_qsort( ref, (size_t)*count, sizeof ( FT_RFork_Ref ),
                     ( int(*)(const void*, const void*) )
                     ft_raccess_sort_ref_by_id );
 
@@ -713,9 +713,9 @@
     FT_UShort  n_of_entries;
 
     int        i;
-    FT_UInt32  entry_id, entry_offset, entry_length = 0;
+    FT_Int32   entry_id, entry_offset, entry_length = 0;
 
-    const FT_UInt32  resource_fork_entry_id = 0x2;
+    const FT_Int32  resource_fork_entry_id = 0x2;
 
     FT_UNUSED( library );
     FT_UNUSED( base_file_name );
@@ -813,7 +813,9 @@
     tmp = ft_strrchr( original_name, '/' );
     if ( tmp )
     {
-      ft_strncpy( new_name, original_name, tmp - original_name + 1 );
+      ft_strncpy( new_name,
+                  original_name,
+                  (size_t)( tmp - original_name + 1 ) );
       new_name[tmp - original_name + 1] = '\0';
       slash = tmp + 1;
     }
diff --git a/src/base/ftsnames.c b/src/base/ftsnames.c
index 260e91c..80304e5 100644
--- a/src/base/ftsnames.c
+++ b/src/base/ftsnames.c
@@ -7,7 +7,7 @@
 /*                                                                         */
 /*    This is _not_ used to retrieve glyph names!                          */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2009 by                                     */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftstream.c b/src/base/ftstream.c
index d965333..b68f3f8 100644
--- a/src/base/ftstream.c
+++ b/src/base/ftstream.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    I/O stream support (body).                                           */
 /*                                                                         */
-/*  Copyright 2000-2002, 2004-2006, 2008-2011, 2013 by                     */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -39,9 +39,9 @@
     stream->base   = (FT_Byte*) base;
     stream->size   = size;
     stream->pos    = 0;
-    stream->cursor = 0;
-    stream->read   = 0;
-    stream->close  = 0;
+    stream->cursor = NULL;
+    stream->read   = NULL;
+    stream->close  = NULL;
   }
 
 
@@ -95,11 +95,11 @@
     if ( distance < 0 )
       return FT_THROW( Invalid_Stream_Operation );
 
-    return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) );
+    return FT_Stream_Seek( stream, stream->pos + (FT_ULong)distance );
   }
 
 
-  FT_BASE_DEF( FT_Long )
+  FT_BASE_DEF( FT_ULong )
   FT_Stream_Pos( FT_Stream  stream )
   {
     return stream->pos;
@@ -203,8 +203,8 @@
       *pbytes = (FT_Byte*)stream->cursor;
 
       /* equivalent to FT_Stream_ExitFrame(), with no memory block release */
-      stream->cursor = 0;
-      stream->limit  = 0;
+      stream->cursor = NULL;
+      stream->limit  = NULL;
     }
 
     return error;
@@ -226,7 +226,7 @@
       FT_FREE( *pbytes );
 #endif
     }
-    *pbytes = 0;
+    *pbytes = NULL;
   }
 
 
@@ -260,7 +260,9 @@
 
 #ifdef FT_DEBUG_MEMORY
       /* assume _ft_debug_file and _ft_debug_lineno are already set */
-      stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error );
+      stream->base = (unsigned char*)ft_mem_qalloc( memory,
+                                                    (FT_Long)count,
+                                                    &error );
       if ( error )
         goto Exit;
 #else
@@ -333,8 +335,8 @@
       FT_FREE( stream->base );
 #endif
     }
-    stream->cursor = 0;
-    stream->limit  = 0;
+    stream->cursor = NULL;
+    stream->limit  = NULL;
   }
 
 
@@ -348,7 +350,7 @@
 
     result = 0;
     if ( stream->cursor < stream->limit )
-      result = *stream->cursor++;
+      result = (FT_Char)*stream->cursor++;
 
     return result;
   }
@@ -357,8 +359,8 @@
   FT_BASE_DEF( FT_UShort )
   FT_Stream_GetUShort( FT_Stream  stream )
   {
-    FT_Byte*  p;
-    FT_Short  result;
+    FT_Byte*   p;
+    FT_UShort  result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -376,8 +378,8 @@
   FT_BASE_DEF( FT_UShort )
   FT_Stream_GetUShortLE( FT_Stream  stream )
   {
-    FT_Byte*  p;
-    FT_Short  result;
+    FT_Byte*   p;
+    FT_UShort  result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -396,7 +398,7 @@
   FT_Stream_GetUOffset( FT_Stream  stream )
   {
     FT_Byte*  p;
-    FT_Long   result;
+    FT_ULong  result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -414,7 +416,7 @@
   FT_Stream_GetULong( FT_Stream  stream )
   {
     FT_Byte*  p;
-    FT_Long   result;
+    FT_ULong  result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -432,7 +434,7 @@
   FT_Stream_GetULongLE( FT_Stream  stream )
   {
     FT_Byte*  p;
-    FT_Long   result;
+    FT_ULong  result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -471,7 +473,7 @@
     }
     stream->pos++;
 
-    return result;
+    return (FT_Char)result;
 
   Fail:
     *error = FT_THROW( Invalid_Stream_Operation );
@@ -485,11 +487,11 @@
 
   FT_BASE_DEF( FT_UShort )
   FT_Stream_ReadUShort( FT_Stream  stream,
-                       FT_Error*  error )
+                        FT_Error*  error )
   {
-    FT_Byte   reads[2];
-    FT_Byte*  p = 0;
-    FT_Short  result = 0;
+    FT_Byte    reads[2];
+    FT_Byte*   p      = 0;
+    FT_UShort  result = 0;
 
 
     FT_ASSERT( stream );
@@ -506,9 +508,7 @@
         p = reads;
       }
       else
-      {
         p = stream->base + stream->pos;
-      }
 
       if ( p )
         result = FT_NEXT_USHORT( p );
@@ -532,11 +532,11 @@
 
   FT_BASE_DEF( FT_UShort )
   FT_Stream_ReadUShortLE( FT_Stream  stream,
-                         FT_Error*  error )
+                          FT_Error*  error )
   {
-    FT_Byte   reads[2];
-    FT_Byte*  p = 0;
-    FT_Short  result = 0;
+    FT_Byte    reads[2];
+    FT_Byte*   p      = 0;
+    FT_UShort  result = 0;
 
 
     FT_ASSERT( stream );
@@ -553,9 +553,7 @@
         p = reads;
       }
       else
-      {
         p = stream->base + stream->pos;
-      }
 
       if ( p )
         result = FT_NEXT_USHORT_LE( p );
@@ -579,11 +577,11 @@
 
   FT_BASE_DEF( FT_ULong )
   FT_Stream_ReadUOffset( FT_Stream  stream,
-                        FT_Error*  error )
+                         FT_Error*  error )
   {
     FT_Byte   reads[3];
-    FT_Byte*  p = 0;
-    FT_Long   result = 0;
+    FT_Byte*  p      = 0;
+    FT_ULong  result = 0;
 
 
     FT_ASSERT( stream );
@@ -600,9 +598,7 @@
         p = reads;
       }
       else
-      {
         p = stream->base + stream->pos;
-      }
 
       if ( p )
         result = FT_NEXT_UOFF3( p );
@@ -626,11 +622,11 @@
 
   FT_BASE_DEF( FT_ULong )
   FT_Stream_ReadULong( FT_Stream  stream,
-                      FT_Error*  error )
+                       FT_Error*  error )
   {
     FT_Byte   reads[4];
-    FT_Byte*  p = 0;
-    FT_Long   result = 0;
+    FT_Byte*  p      = 0;
+    FT_ULong  result = 0;
 
 
     FT_ASSERT( stream );
@@ -647,9 +643,7 @@
         p = reads;
       }
       else
-      {
         p = stream->base + stream->pos;
-      }
 
       if ( p )
         result = FT_NEXT_ULONG( p );
@@ -673,11 +667,11 @@
 
   FT_BASE_DEF( FT_ULong )
   FT_Stream_ReadULongLE( FT_Stream  stream,
-                        FT_Error*  error )
+                         FT_Error*  error )
   {
     FT_Byte   reads[4];
-    FT_Byte*  p = 0;
-    FT_Long   result = 0;
+    FT_Byte*  p      = 0;
+    FT_ULong  result = 0;
 
 
     FT_ASSERT( stream );
@@ -694,9 +688,7 @@
         p = reads;
       }
       else
-      {
         p = stream->base + stream->pos;
-      }
 
       if ( p )
         result = FT_NEXT_ULONG_LE( p );
@@ -728,9 +720,12 @@
     FT_Byte*  cursor;
 
 
-    if ( !fields || !stream )
+    if ( !fields )
       return FT_THROW( Invalid_Argument );
 
+    if ( !stream )
+      return FT_THROW( Invalid_Stream_Handle );
+
     cursor = stream->cursor;
 
     error = FT_Err_Ok;
diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c
index ee61cec..842ee30 100644
--- a/src/base/ftstroke.c
+++ b/src/base/ftstroke.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType path stroker (body).                                        */
 /*                                                                         */
-/*  Copyright 2002-2006, 2008-2011, 2013 by                                */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -347,7 +347,7 @@
   ft_stroke_border_close( FT_StrokeBorder  border,
                           FT_Bool          reverse )
   {
-    FT_UInt  start = border->start;
+    FT_UInt  start = (FT_UInt)border->start;
     FT_UInt  count = border->num_points;
 
 
@@ -599,7 +599,7 @@
     if ( border->start >= 0 )
       ft_stroke_border_close( border, FALSE );
 
-    border->start = border->num_points;
+    border->start = (FT_Int)border->num_points;
     border->movable = FALSE;
 
     return ft_stroke_border_lineto( border, to, FALSE );
@@ -742,7 +742,7 @@
       }
     }
 
-    outline->n_points = (short)( outline->n_points + border->num_points );
+    outline->n_points += (short)border->num_points;
 
     FT_ASSERT( FT_Outline_Check( outline ) == 0 );
   }
@@ -795,6 +795,9 @@
 
 
     if ( !library )
+      return FT_THROW( Invalid_Library_Handle );
+
+    if ( !astroker )
       return FT_THROW( Invalid_Argument );
 
     memory = library->memory;
@@ -822,14 +825,17 @@
                   FT_Stroker_LineJoin  line_join,
                   FT_Fixed             miter_limit )
   {
+    if ( !stroker )
+      return;
+
     stroker->radius      = radius;
     stroker->line_cap    = line_cap;
     stroker->line_join   = line_join;
     stroker->miter_limit = miter_limit;
 
     /* ensure miter limit has sensible value */
-    if ( stroker->miter_limit < 0x10000 )
-      stroker->miter_limit = 0x10000;
+    if ( stroker->miter_limit < 0x10000L )
+      stroker->miter_limit = 0x10000L;
 
     /* save line join style:                                           */
     /* line join style can be temporarily changed when stroking curves */
@@ -993,7 +999,9 @@
 
     /* Only intersect borders if between two lineto's and both */
     /* lines are long enough (line_length is zero for curves). */
-    if ( !border->movable || line_length == 0 )
+    /* Also avoid U-turns of nearly 180 degree.                */
+    if ( !border->movable || line_length == 0  ||
+         theta > 0x59C000 || theta < -0x59C000 )
       intersect = FALSE;
     else
     {
@@ -1002,7 +1010,8 @@
                                                     FT_Tan( theta ) ) );
 
 
-      intersect = FT_BOOL( stroker->line_length >= min_length &&
+      intersect = FT_BOOL( min_length                         &&
+                           stroker->line_length >= min_length &&
                            line_length          >= min_length );
     }
 
@@ -1213,11 +1222,8 @@
       goto Exit;
 
     /* when we turn to the right, the inside side is 0 */
-    inside_side = 0;
-
     /* otherwise, the inside side is 1 */
-    if ( turn < 0 )
-      inside_side = 1;
+    inside_side = ( turn < 0 );
 
     /* process the inside side */
     error = ft_stroker_inside( stroker, inside_side, line_length );
@@ -1225,7 +1231,7 @@
       goto Exit;
 
     /* process the outside side */
-    error = ft_stroker_outside( stroker, 1 - inside_side, line_length );
+    error = ft_stroker_outside( stroker, !inside_side, line_length );
 
   Exit:
     return error;
@@ -1287,6 +1293,9 @@
     FT_Fixed         line_length;
 
 
+    if ( !stroker || !to )
+      return FT_THROW( Invalid_Argument );
+
     delta.x = to->x - stroker->center.x;
     delta.y = to->y - stroker->center.y;
 
@@ -1360,6 +1369,12 @@
     FT_Bool     first_arc = TRUE;
 
 
+    if ( !stroker || !control || !to )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
     /* if all control points are coincident, this is a no-op; */
     /* avoid creating a spurious corner                       */
     if ( FT_IS_SMALL( stroker->center.x - control->x ) &&
@@ -1556,6 +1571,12 @@
     FT_Bool     first_arc = TRUE;
 
 
+    if ( !stroker || !control1 || !control2 || !to )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
     /* if all control points are coincident, this is a no-op; */
     /* avoid creating a spurious corner */
     if ( FT_IS_SMALL( stroker->center.x - control1->x ) &&
@@ -1758,6 +1779,9 @@
                            FT_Vector*  to,
                            FT_Bool     open )
   {
+    if ( !stroker || !to )
+      return FT_THROW( Invalid_Argument );
+
     /* We cannot process the first point, because there is not enough      */
     /* information regarding its corner/cap.  The latter will be processed */
     /* in the `FT_Stroker_EndSubPath' routine.                             */
@@ -1797,7 +1821,7 @@
 
     FT_ASSERT( left->start >= 0 );
 
-    new_points = left->num_points - left->start;
+    new_points = (FT_Int)left->num_points - left->start;
     if ( new_points > 0 )
     {
       error = ft_stroke_border_grow( right, (FT_UInt)new_points );
@@ -1837,8 +1861,8 @@
         }
       }
 
-      left->num_points   = left->start;
-      right->num_points += new_points;
+      left->num_points   = (FT_UInt)left->start;
+      right->num_points += (FT_UInt)new_points;
 
       right->movable = FALSE;
       left->movable  = FALSE;
@@ -1858,6 +1882,12 @@
     FT_Error  error = FT_Err_Ok;
 
 
+    if ( !stroker )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
     if ( stroker->subpath_open )
     {
       FT_StrokeBorder  right = stroker->borders;
@@ -1910,11 +1940,8 @@
       if ( turn != 0 )
       {
         /* when we turn to the right, the inside side is 0 */
-        inside_side = 0;
-
         /* otherwise, the inside side is 1 */
-        if ( turn < 0 )
-          inside_side = 1;
+        inside_side = ( turn < 0 );
 
         error = ft_stroker_inside( stroker,
                                    inside_side,
@@ -1924,7 +1951,7 @@
 
         /* process the outside side */
         error = ft_stroker_outside( stroker,
-                                    1 - inside_side,
+                                    !inside_side,
                                     stroker->subpath_line_length );
         if ( error )
           goto Exit;
@@ -1983,6 +2010,12 @@
     FT_Error  error;
 
 
+    if ( !stroker )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
     error = ft_stroke_border_get_counts( stroker->borders + 0,
                                          &count1, &count2 );
     if ( error )
@@ -1997,8 +2030,12 @@
     num_contours = count2 + count4;
 
   Exit:
-    *anum_points   = num_points;
-    *anum_contours = num_contours;
+    if ( anum_points )
+      *anum_points   = num_points;
+
+    if ( anum_contours )
+      *anum_contours = num_contours;
+
     return error;
   }
 
@@ -2010,6 +2047,9 @@
                            FT_StrokerBorder  border,
                            FT_Outline*       outline )
   {
+    if ( !stroker || !outline )
+      return;
+
     if ( border == FT_STROKER_BORDER_LEFT  ||
          border == FT_STROKER_BORDER_RIGHT )
     {
@@ -2059,7 +2099,10 @@
     FT_Int      tag;       /* current point's state           */
 
 
-    if ( !outline || !stroker )
+    if ( !outline )
+      return FT_THROW( Invalid_Outline );
+
+    if ( !stroker )
       return FT_THROW( Invalid_Argument );
 
     FT_Stroker_Rewind( stroker );
@@ -2071,7 +2114,7 @@
       FT_UInt  last;  /* index of last point in contour */
 
 
-      last  = outline->contours[n];
+      last  = (FT_UInt)outline->contours[n];
       limit = outline->points + last;
 
       /* skip empty points; we don't stroke these */
@@ -2258,18 +2301,20 @@
                    FT_Stroker   stroker,
                    FT_Bool      destroy )
   {
-    FT_Error    error   = FT_ERR( Invalid_Argument );
-    FT_Glyph    glyph   = NULL;
+    FT_Error  error = FT_ERR( Invalid_Argument );
+    FT_Glyph  glyph = NULL;
+
+    /* for FT_OUTLINE_GLYPH_CLASS_GET (in PIC mode) */
     FT_Library  library = stroker->library;
 
     FT_UNUSED( library );
 
 
-    if ( pglyph == NULL )
+    if ( !pglyph )
       goto Exit;
 
     glyph = *pglyph;
-    if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET )
+    if ( !glyph || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET )
       goto Exit;
 
     {
@@ -2293,12 +2338,14 @@
       if ( error )
         goto Fail;
 
-      (void)FT_Stroker_GetCounts( stroker, &num_points, &num_contours );
+      FT_Stroker_GetCounts( stroker, &num_points, &num_contours );
 
       FT_Outline_Done( glyph->library, outline );
 
       error = FT_Outline_New( glyph->library,
-                              num_points, num_contours, outline );
+                              num_points,
+                              (FT_Int)num_contours,
+                              outline );
       if ( error )
         goto Fail;
 
@@ -2334,18 +2381,20 @@
                          FT_Bool      inside,
                          FT_Bool      destroy )
   {
-    FT_Error    error   = FT_ERR( Invalid_Argument );
-    FT_Glyph    glyph   = NULL;
+    FT_Error  error = FT_ERR( Invalid_Argument );
+    FT_Glyph  glyph = NULL;
+
+    /* for FT_OUTLINE_GLYPH_CLASS_GET (in PIC mode) */
     FT_Library  library = stroker->library;
 
     FT_UNUSED( library );
 
 
-    if ( pglyph == NULL )
+    if ( !pglyph )
       goto Exit;
 
     glyph = *pglyph;
-    if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET )
+    if ( !glyph || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET )
       goto Exit;
 
     {
@@ -2379,14 +2428,14 @@
       if ( error )
         goto Fail;
 
-      (void)FT_Stroker_GetBorderCounts( stroker, border,
-                                        &num_points, &num_contours );
+      FT_Stroker_GetBorderCounts( stroker, border,
+                                  &num_points, &num_contours );
 
       FT_Outline_Done( glyph->library, outline );
 
       error = FT_Outline_New( glyph->library,
                               num_points,
-                              num_contours,
+                              (FT_Int)num_contours,
                               outline );
       if ( error )
         goto Fail;
diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c
index 3098a60..cd68533 100644
--- a/src/base/ftsynth.c
+++ b/src/base/ftsynth.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType synthesizing code for emboldening and slanting (body).      */
 /*                                                                         */
-/*  Copyright 2000-2006, 2010, 2012, 2013 by                               */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -48,9 +48,14 @@
   FT_GlyphSlot_Oblique( FT_GlyphSlot  slot )
   {
     FT_Matrix    transform;
-    FT_Outline*  outline = &slot->outline;
+    FT_Outline*  outline;
 
 
+    if ( !slot )
+      return;
+
+    outline = &slot->outline;
+
     /* only oblique outline glyphs */
     if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
       return;
@@ -84,12 +89,18 @@
   FT_EXPORT_DEF( void )
   FT_GlyphSlot_Embolden( FT_GlyphSlot  slot )
   {
-    FT_Library  library = slot->library;
-    FT_Face     face    = slot->face;
+    FT_Library  library;
+    FT_Face     face;
     FT_Error    error;
     FT_Pos      xstr, ystr;
 
 
+    if ( !slot )
+      return;
+
+    library = slot->library;
+    face    = slot->face;
+
     if ( slot->format != FT_GLYPH_FORMAT_OUTLINE &&
          slot->format != FT_GLYPH_FORMAT_BITMAP  )
       return;
@@ -100,10 +111,8 @@
     ystr = xstr;
 
     if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
-    {
-      /* ignore error */
-      (void)FT_Outline_EmboldenXY( &slot->outline, xstr, ystr );
-    }
+      FT_Outline_EmboldenXY( &slot->outline, xstr, ystr );
+
     else /* slot->format == FT_GLYPH_FORMAT_BITMAP */
     {
       /* round to full pixels */
diff --git a/src/base/ftsystem.c b/src/base/ftsystem.c
index 2c6ddac..1938fd8 100644
--- a/src/base/ftsystem.c
+++ b/src/base/ftsystem.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    ANSI-specific FreeType low-level system interface (body).            */
 /*                                                                         */
-/*  Copyright 1996-2002, 2006, 2008-2011, 2013 by                          */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -71,7 +71,7 @@
   {
     FT_UNUSED( memory );
 
-    return ft_smalloc( size );
+    return ft_smalloc( (size_t)size );
   }
 
 
@@ -104,7 +104,7 @@
     FT_UNUSED( memory );
     FT_UNUSED( cur_size );
 
-    return ft_srealloc( block, new_size );
+    return ft_srealloc( block, (size_t)new_size );
   }
 
 
@@ -171,7 +171,7 @@
 
     stream->descriptor.pointer = NULL;
     stream->size               = 0;
-    stream->base               = 0;
+    stream->base               = NULL;
   }
 
 
@@ -212,7 +212,7 @@
     file = STREAM_FILE( stream );
 
     if ( stream->pos != offset )
-      ft_fseek( file, offset, SEEK_SET );
+      ft_fseek( file, (long)offset, SEEK_SET );
 
     return (unsigned long)ft_fread( buffer, 1, count, file );
   }
@@ -232,7 +232,7 @@
 
     stream->descriptor.pointer = NULL;
     stream->pathname.pointer   = (char*)filepathname;
-    stream->base               = 0;
+    stream->base               = NULL;
     stream->pos                = 0;
     stream->read               = NULL;
     stream->close              = NULL;
@@ -247,7 +247,7 @@
     }
 
     ft_fseek( file, 0, SEEK_END );
-    stream->size = ft_ftell( file );
+    stream->size = (unsigned long)ft_ftell( file );
     if ( !stream->size )
     {
       FT_ERROR(( "FT_Stream_Open:" ));
@@ -292,7 +292,7 @@
     memory = (FT_Memory)ft_smalloc( sizeof ( *memory ) );
     if ( memory )
     {
-      memory->user    = 0;
+      memory->user    = NULL;
       memory->alloc   = ft_alloc;
       memory->realloc = ft_realloc;
       memory->free    = ft_free;
diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c
index 4ffdcb7..5b24304 100644
--- a/src/base/fttrigon.c
+++ b/src/base/fttrigon.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType trigonometric functions (body).                             */
 /*                                                                         */
-/*  Copyright 2001-2005, 2012-2013 by                                      */
+/*  Copyright 2001-2015 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 @@
   /* this table was generated for FT_PI = 180L << 16, i.e. degrees */
 #define FT_TRIG_MAX_ITERS  23
 
-  static const FT_Fixed
+  static const FT_Angle
   ft_trig_arctan_table[] =
   {
     1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L,
@@ -60,17 +60,20 @@
   static FT_Fixed
   ft_trig_downscale( FT_Fixed  val )
   {
-    FT_Fixed  s;
-    FT_Int64  v;
+    FT_Int  s = 1;
 
 
-    s   = val;
-    val = FT_ABS( val );
+    if ( val < 0 )
+    {
+       val = -val;
+       s = -1;
+    }
 
-    v   = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL;
-    val = (FT_Fixed)( v >> 32 );
+    /* 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 );
 
-    return ( s >= 0 ) ? val : -val;
+    return s < 0 ? -val : val;
   }
 
 #else /* !FT_LONG64 */
@@ -79,38 +82,53 @@
   static FT_Fixed
   ft_trig_downscale( FT_Fixed  val )
   {
-    FT_Fixed   s;
-    FT_UInt32  v1, v2, k1, k2, hi, lo1, lo2, lo3;
+    FT_Int     s = 1;
+    FT_UInt32  lo1, hi1, lo2, hi2, lo, hi, i1, i2;
 
 
-    s   = val;
-    val = FT_ABS( val );
+    if ( val < 0 )
+    {
+       val = -val;
+       s = -1;
+    }
 
-    v1 = (FT_UInt32)val >> 16;
-    v2 = (FT_UInt32)( val & 0xFFFFL );
+    lo1 = (FT_UInt32)val & 0x0000FFFFU;
+    hi1 = (FT_UInt32)val >> 16;
+    lo2 = FT_TRIG_SCALE & 0x0000FFFFU;
+    hi2 = FT_TRIG_SCALE >> 16;
 
-    k1 = (FT_UInt32)FT_TRIG_SCALE >> 16;           /* constant */
-    k2 = (FT_UInt32)( FT_TRIG_SCALE & 0xFFFFL );   /* constant */
+    lo = lo1 * lo2;
+    i1 = lo1 * hi2;
+    i2 = lo2 * hi1;
+    hi = hi1 * hi2;
 
-    hi   = k1 * v1;
-    lo1  = k1 * v2 + k2 * v1;       /* can't overflow */
+    /* Check carry overflow of i1 + i2 */
+    i1 += i2;
+    hi += (FT_UInt32)( i1 < i2 ) << 16;
 
-    lo2  = ( k2 * v2 ) >> 16;
-    lo3  = FT_MAX( lo1, lo2 );
-    lo1 += lo2;
+    hi += i1 >> 16;
+    i1  = i1 << 16;
 
-    hi  += lo1 >> 16;
-    if ( lo1 < lo3 )
-      hi += (FT_UInt32)0x10000UL;
+    /* Check carry overflow of i1 + lo */
+    lo += i1;
+    hi += ( lo < i1 );
 
-    val  = (FT_Fixed)hi;
+    /* 0x40000000 comes from regression analysis between true */
+    /* and CORDIC hypotenuse, so it minimizes the error       */
 
-    return ( s >= 0 ) ? val : -val;
+    /* Check carry overflow of lo + 0x40000000 */
+    lo += 0x40000000UL;
+    hi += ( lo < 0x40000000UL );
+
+    val = (FT_Fixed)hi;
+
+    return s < 0 ? -val : val;
   }
 
 #endif /* !FT_LONG64 */
 
 
+  /* undefined and never called for zero vector */
   static FT_Int
   ft_trig_prenorm( FT_Vector*  vec )
   {
@@ -121,7 +139,7 @@
     x = vec->x;
     y = vec->y;
 
-    shift = FT_MSB( FT_ABS( x ) | FT_ABS( y ) );
+    shift = FT_MSB( (FT_UInt32)( FT_ABS( x ) | FT_ABS( y ) ) );
 
     if ( shift <= FT_TRIG_SAFE_MSB )
     {
@@ -147,7 +165,7 @@
   {
     FT_Int           i;
     FT_Fixed         x, y, xtemp, b;
-    const FT_Fixed  *arctanptr;
+    const FT_Angle  *arctanptr;
 
 
     x = vec->x;
@@ -202,7 +220,7 @@
     FT_Angle         theta;
     FT_Int           i;
     FT_Fixed         x, y, xtemp, b;
-    const FT_Fixed  *arctanptr;
+    const FT_Angle  *arctanptr;
 
 
     x = vec->x;
@@ -261,11 +279,12 @@
       }
     }
 
-    /* round theta */
+    /* round theta to acknowledge its error that mostly comes */
+    /* from accumulated rounding errors in the arctan table   */
     if ( theta >= 0 )
-      theta = FT_PAD_ROUND( theta, 32 );
+      theta = FT_PAD_ROUND( theta, 16 );
     else
-      theta = -FT_PAD_ROUND( -theta, 32 );
+      theta = -FT_PAD_ROUND( -theta, 16 );
 
     vec->x = x;
     vec->y = theta;
@@ -280,11 +299,9 @@
     FT_Vector  v;
 
 
-    v.x = FT_TRIG_SCALE >> 8;
-    v.y = 0;
-    ft_trig_pseudo_rotate( &v, angle );
+    FT_Vector_Unit( &v, angle );
 
-    return ( v.x + 0x80L ) >> 8;
+    return v.x;
   }
 
 
@@ -293,7 +310,12 @@
   FT_EXPORT_DEF( FT_Fixed )
   FT_Sin( FT_Angle  angle )
   {
-    return FT_Cos( FT_ANGLE_PI2 - angle );
+    FT_Vector  v;
+
+
+    FT_Vector_Unit( &v, angle );
+
+    return v.y;
   }
 
 
@@ -305,9 +327,7 @@
     FT_Vector  v;
 
 
-    v.x = FT_TRIG_SCALE >> 8;
-    v.y = 0;
-    ft_trig_pseudo_rotate( &v, angle );
+    FT_Vector_Unit( &v, angle );
 
     return FT_DivFix( v.y, v.x );
   }
@@ -340,6 +360,9 @@
   FT_Vector_Unit( FT_Vector*  vec,
                   FT_Angle    angle )
   {
+    if ( !vec )
+      return;
+
     vec->x = FT_TRIG_SCALE >> 8;
     vec->y = 0;
     ft_trig_pseudo_rotate( vec, angle );
@@ -366,30 +389,32 @@
     FT_Vector  v;
 
 
-    v.x   = vec->x;
-    v.y   = vec->y;
+    if ( !vec || !angle )
+      return;
 
-    if ( angle && ( v.x != 0 || v.y != 0 ) )
+    v = *vec;
+
+    if ( v.x == 0 && v.y == 0 )
+      return;
+
+    shift = ft_trig_prenorm( &v );
+    ft_trig_pseudo_rotate( &v, angle );
+    v.x = ft_trig_downscale( v.x );
+    v.y = ft_trig_downscale( v.y );
+
+    if ( shift > 0 )
     {
-      shift = ft_trig_prenorm( &v );
-      ft_trig_pseudo_rotate( &v, angle );
-      v.x = ft_trig_downscale( v.x );
-      v.y = ft_trig_downscale( v.y );
-
-      if ( shift > 0 )
-      {
-        FT_Int32  half = (FT_Int32)1L << ( shift - 1 );
+      FT_Int32  half = (FT_Int32)1L << ( shift - 1 );
 
 
-        vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift;
-        vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift;
-      }
-      else
-      {
-        shift  = -shift;
-        vec->x = (FT_Pos)( (FT_ULong)v.x << shift );
-        vec->y = (FT_Pos)( (FT_ULong)v.y << shift );
-      }
+      vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift;
+      vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift;
+    }
+    else
+    {
+      shift  = -shift;
+      vec->x = (FT_Pos)( (FT_ULong)v.x << shift );
+      vec->y = (FT_Pos)( (FT_ULong)v.y << shift );
     }
   }
 
@@ -403,6 +428,9 @@
     FT_Vector  v;
 
 
+    if ( !vec )
+      return 0;
+
     v = *vec;
 
     /* handle trivial cases */
@@ -422,7 +450,7 @@
     v.x = ft_trig_downscale( v.x );
 
     if ( shift > 0 )
-      return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift;
+      return ( v.x + ( 1L << ( shift - 1 ) ) ) >> shift;
 
     return (FT_Fixed)( (FT_UInt32)v.x << -shift );
   }
@@ -439,6 +467,9 @@
     FT_Vector  v;
 
 
+    if ( !vec || !length || !angle )
+      return;
+
     v = *vec;
 
     if ( v.x == 0 && v.y == 0 )
@@ -449,8 +480,8 @@
 
     v.x = ft_trig_downscale( v.x );
 
-    *length = ( shift >= 0 ) ?                      ( v.x >>  shift )
-                             : (FT_Fixed)( (FT_UInt32)v.x << -shift );
+    *length = shift >= 0 ?                      ( v.x >>  shift )
+                         : (FT_Fixed)( (FT_UInt32)v.x << -shift );
     *angle  = v.y;
   }
 
@@ -462,6 +493,9 @@
                         FT_Fixed    length,
                         FT_Angle    angle )
   {
+    if ( !vec )
+      return;
+
     vec->x = length;
     vec->y = 0;
 
@@ -478,11 +512,10 @@
     FT_Angle  delta = angle2 - angle1;
 
 
-    delta %= FT_ANGLE_2PI;
-    if ( delta < 0 )
+    while ( delta <= -FT_ANGLE_PI )
       delta += FT_ANGLE_2PI;
 
-    if ( delta > FT_ANGLE_PI )
+    while ( delta > FT_ANGLE_PI )
       delta -= FT_ANGLE_2PI;
 
     return delta;
diff --git a/src/base/fttype1.c b/src/base/fttype1.c
index 1d17402..c549382 100644
--- a/src/base/fttype1.c
+++ b/src/base/fttype1.c
@@ -1,114 +1,127 @@
-/***************************************************************************/

-/*                                                                         */

-/*  fttype1.c                                                              */

-/*                                                                         */

-/*    FreeType utility file for PS names support (body).                   */

-/*                                                                         */

-/*  Copyright 2002-2004, 2011 by                                           */

-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */

-/*                                                                         */

-/*  This file is part of the FreeType project, and may only be used,       */

-/*  modified, and distributed under the terms of the FreeType project      */

-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */

-/*  this file you indicate that you have read the license and              */

-/*  understand and accept it fully.                                        */

-/*                                                                         */

-/***************************************************************************/

-

-

-#include <ft2build.h>

-#include FT_INTERNAL_OBJECTS_H

-#include FT_INTERNAL_SERVICE_H

-#include FT_SERVICE_POSTSCRIPT_INFO_H

-

-

-  /* documentation is in t1tables.h */

-

-  FT_EXPORT_DEF( FT_Error )

-  FT_Get_PS_Font_Info( FT_Face          face,

-                       PS_FontInfoRec*  afont_info )

-  {

-    FT_Error  error = FT_ERR( Invalid_Argument );

-

-

-    if ( face )

-    {

-      FT_Service_PsInfo  service = NULL;

-

-

-      FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );

-

-      if ( service && service->ps_get_font_info )

-        error = service->ps_get_font_info( face, afont_info );

-    }

-

-    return error;

-  }

-

-

-  /* documentation is in t1tables.h */

-

-  FT_EXPORT_DEF( FT_Int )

-  FT_Has_PS_Glyph_Names( FT_Face  face )

-  {

-    FT_Int             result  = 0;

-    FT_Service_PsInfo  service = NULL;

-

-

-    if ( face )

-    {

-      FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );

-

-      if ( service && service->ps_has_glyph_names )

-        result = service->ps_has_glyph_names( face );

-    }

-

-    return result;

-  }

-

-

-  /* documentation is in t1tables.h */

-

-  FT_EXPORT_DEF( FT_Error )

-  FT_Get_PS_Font_Private( FT_Face         face,

-                          PS_PrivateRec*  afont_private )

-  {

-    FT_Error  error = FT_ERR( Invalid_Argument );

-

-

-    if ( face )

-    {

-      FT_Service_PsInfo  service = NULL;

-

-

-      FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );

-

-      if ( service && service->ps_get_font_private )

-        error = service->ps_get_font_private( face, afont_private );

-    }

-

-    return error;

-  }

-

-/* documentation is in t1tables.h */

-FT_EXPORT_DEF( FT_Long )

-FT_Get_PS_Font_Value( FT_Face       face,

-                      PS_Dict_Keys  key,

-                      FT_UInt       idx,

-                      void         *value,

-                      FT_Long       value_len )

-{

-  FT_Int             result  = 0;

-  FT_Service_PsInfo  service = NULL;

-

-  if ( face )

-  {

-    FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );

-      if ( service && service->ps_get_font_value )

-      result = service->ps_get_font_value( face, key, idx,

-                                           value, value_len );

-  }

-  return result;

-}

-

-/* END */

+/***************************************************************************/
+/*                                                                         */
+/*  fttype1.c                                                              */
+/*                                                                         */
+/*    FreeType utility file for PS names support (body).                   */
+/*                                                                         */
+/*  Copyright 2002-2015 by                                                 */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_OBJECTS_H
+#include FT_INTERNAL_SERVICE_H
+#include FT_SERVICE_POSTSCRIPT_INFO_H
+
+
+  /* documentation is in t1tables.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_PS_Font_Info( FT_Face          face,
+                       PS_FontInfoRec*  afont_info )
+  {
+    FT_Error           error;
+    FT_Service_PsInfo  service;
+
+
+    if ( !face )
+      return FT_THROW( Invalid_Face_Handle );
+
+    if ( !afont_info )
+      return FT_THROW( Invalid_Argument );
+
+    FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
+
+    if ( service && service->ps_get_font_info )
+      error = service->ps_get_font_info( face, afont_info );
+    else
+      error = FT_THROW( Invalid_Argument );
+
+    return error;
+  }
+
+
+  /* documentation is in t1tables.h */
+
+  FT_EXPORT_DEF( FT_Int )
+  FT_Has_PS_Glyph_Names( FT_Face  face )
+  {
+    FT_Int             result = 0;
+    FT_Service_PsInfo  service;
+
+
+    if ( face )
+    {
+      FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
+
+      if ( service && service->ps_has_glyph_names )
+        result = service->ps_has_glyph_names( face );
+    }
+
+    return result;
+  }
+
+
+  /* documentation is in t1tables.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_PS_Font_Private( FT_Face         face,
+                          PS_PrivateRec*  afont_private )
+  {
+    FT_Error           error;
+    FT_Service_PsInfo  service;
+
+
+    if ( !face )
+      return FT_THROW( Invalid_Face_Handle );
+
+    if ( !afont_private )
+      return FT_THROW( Invalid_Argument );
+
+    FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
+
+    if ( service && service->ps_get_font_private )
+      error = service->ps_get_font_private( face, afont_private );
+    else
+      error = FT_THROW( Invalid_Argument );
+
+    return error;
+  }
+
+
+  /* documentation is in t1tables.h */
+
+  FT_EXPORT_DEF( FT_Long )
+  FT_Get_PS_Font_Value( FT_Face       face,
+                        PS_Dict_Keys  key,
+                        FT_UInt       idx,
+                        void         *value,
+                        FT_Long       value_len )
+  {
+    FT_Int             result  = 0;
+    FT_Service_PsInfo  service = NULL;
+
+
+    if ( face )
+    {
+      FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
+
+      if ( service && service->ps_get_font_value )
+        result = service->ps_get_font_value( face, key, idx,
+                                             value, value_len );
+    }
+
+    return result;
+  }
+
+
+/* END */
diff --git a/src/base/ftutil.c b/src/base/ftutil.c
index 9f37189..f5b72db 100644
--- a/src/base/ftutil.c
+++ b/src/base/ftutil.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility file for memory and list management (body).         */
 /*                                                                         */
-/*  Copyright 2002, 2004-2007, 2013 by                                     */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -180,7 +180,7 @@
               FT_Error    *p_error )
   {
     FT_Error    error;
-    FT_Pointer  p = ft_mem_qalloc( memory, size, &error );
+    FT_Pointer  p = ft_mem_qalloc( memory, (FT_Long)size, &error );
 
 
     if ( !error && address )
@@ -245,6 +245,9 @@
     FT_ListNode  cur;
 
 
+    if ( !list )
+      return NULL;
+
     cur = list->head;
     while ( cur )
     {
@@ -254,7 +257,7 @@
       cur = cur->next;
     }
 
-    return (FT_ListNode)0;
+    return NULL;
   }
 
 
@@ -264,10 +267,15 @@
   FT_List_Add( FT_List      list,
                FT_ListNode  node )
   {
-    FT_ListNode  before = list->tail;
+    FT_ListNode  before;
 
 
-    node->next = 0;
+    if ( !list || !node )
+      return;
+
+    before = list->tail;
+
+    node->next = NULL;
     node->prev = before;
 
     if ( before )
@@ -285,11 +293,16 @@
   FT_List_Insert( FT_List      list,
                   FT_ListNode  node )
   {
-    FT_ListNode  after = list->head;
+    FT_ListNode  after;
 
 
+    if ( !list || !node )
+      return;
+
+    after = list->head;
+
     node->next = after;
-    node->prev = 0;
+    node->prev = NULL;
 
     if ( !after )
       list->tail = node;
@@ -309,6 +322,9 @@
     FT_ListNode  before, after;
 
 
+    if ( !list || !node )
+      return;
+
     before = node->prev;
     after  = node->next;
 
@@ -333,6 +349,9 @@
     FT_ListNode  before, after;
 
 
+    if ( !list || !node )
+      return;
+
     before = node->prev;
     after  = node->next;
 
@@ -347,7 +366,7 @@
     else
       list->tail = before;
 
-    node->prev       = 0;
+    node->prev       = NULL;
     node->next       = list->head;
     list->head->prev = node;
     list->head       = node;
@@ -357,14 +376,19 @@
   /* documentation is in ftlist.h */
 
   FT_EXPORT_DEF( FT_Error )
-  FT_List_Iterate( FT_List            list,
-                   FT_List_Iterator   iterator,
-                   void*              user )
+  FT_List_Iterate( FT_List           list,
+                   FT_List_Iterator  iterator,
+                   void*             user )
   {
-    FT_ListNode  cur   = list->head;
+    FT_ListNode  cur;
     FT_Error     error = FT_Err_Ok;
 
 
+    if ( !list || !iterator )
+      return FT_THROW( Invalid_Argument );
+
+    cur = list->head;
+
     while ( cur )
     {
       FT_ListNode  next = cur->next;
@@ -392,6 +416,9 @@
     FT_ListNode  cur;
 
 
+    if ( !list || !memory )
+      return;
+
     cur = list->head;
     while ( cur )
     {
@@ -406,8 +433,8 @@
       cur = next;
     }
 
-    list->head = 0;
-    list->tail = 0;
+    list->head = NULL;
+    list->tail = NULL;
   }
 
 
diff --git a/src/base/ftwinfnt.c b/src/base/ftwinfnt.c
index 463ae76..76a19af 100644
--- a/src/base/ftwinfnt.c
+++ b/src/base/ftwinfnt.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for accessing Windows FNT specific info (body).         */
 /*                                                                         */
-/*  Copyright 2003, 2004 by                                                */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -17,6 +17,7 @@
 
 
 #include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
 #include FT_WINFONTS_H
 #include FT_INTERNAL_OBJECTS_H
 #include FT_SERVICE_WINFNT_H
@@ -32,17 +33,18 @@
     FT_Error           error;
 
 
-    error = FT_ERR( Invalid_Argument );
+    if ( !face )
+      return FT_THROW( Invalid_Face_Handle );
 
-    if ( face != NULL )
-    {
-      FT_FACE_LOOKUP_SERVICE( face, service, WINFNT );
+    if ( !header )
+      return FT_THROW( Invalid_Argument );
 
-      if ( service != NULL )
-      {
-        error = service->get_header( face, header );
-      }
-    }
+    FT_FACE_LOOKUP_SERVICE( face, service, WINFNT );
+
+    if ( service )
+      error = service->get_header( face, header );
+    else
+      error = FT_THROW( Invalid_Argument );
 
     return error;
   }
diff --git a/src/cache/ftcbasic.c b/src/cache/ftcbasic.c
index 01be88c..ac3290c 100644
--- a/src/cache/ftcbasic.c
+++ b/src/cache/ftcbasic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType basic cache interface (body).                           */
 /*                                                                         */
-/*  Copyright 2003-2007, 2009-2011, 2013, 2014 by                          */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -45,8 +45,8 @@
           FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \
                    (a)->load_flags == (b)->load_flags               )
 
-#define FTC_BASIC_ATTR_HASH( a )                                   \
-          ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags )
+#define FTC_BASIC_ATTR_HASH( a )                                     \
+          ( FTC_SCALER_HASH( &(a)->scaler ) + 31 * (a)->load_flags )
 
 
   typedef struct  FTC_BasicQueryRec_
@@ -110,10 +110,9 @@
       return result;
 
     if ( (FT_ULong)face->num_glyphs > FT_UINT_MAX || 0 > face->num_glyphs )
-    {
-      FT_TRACE1(( "ftc_basic_family_get_count: too large number of glyphs " ));
-      FT_TRACE1(( "in this face, truncated\n", face->num_glyphs ));
-    }
+      FT_TRACE1(( "ftc_basic_family_get_count:"
+                  " too large number of glyphs in this face, truncated\n",
+                  face->num_glyphs ));
 
     if ( !error )
       result = (FT_UInt)face->num_glyphs;
@@ -139,8 +138,10 @@
       FT_Face  face = size->face;
 
 
-      error = FT_Load_Glyph( face, gindex,
-                             family->attrs.load_flags | FT_LOAD_RENDER );
+      error = FT_Load_Glyph(
+                face,
+                gindex,
+                (FT_Int)family->attrs.load_flags | FT_LOAD_RENDER );
       if ( !error )
         *aface = face;
     }
@@ -170,7 +171,9 @@
     {
       face = size->face;
 
-      error = FT_Load_Glyph( face, gindex, family->attrs.load_flags );
+      error = FT_Load_Glyph( face,
+                             gindex,
+                             (FT_Int)family->attrs.load_flags );
       if ( !error )
       {
         if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP  ||
@@ -284,10 +287,10 @@
     FTC_BasicQueryRec  query;
     FTC_Node           node = 0; /* make compiler happy */
     FT_Error           error;
-    FT_PtrDist         hash;
+    FT_Offset          hash;
 
 
-    /* some argument checks are delayed to FTC_Cache_Lookup */
+    /* some argument checks are delayed to `FTC_Cache_Lookup' */
     if ( !aglyph )
     {
       error = FT_THROW( Invalid_Argument );
@@ -298,18 +301,15 @@
     if ( anode )
       *anode  = NULL;
 
-    {
-      if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX )
-      {
-        FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));
-        FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) ));
-      }
+    if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX )
+      FT_TRACE1(( "FTC_ImageCache_Lookup:"
+                  " higher bits in load_flags 0x%x are dropped\n",
+                  (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) ));
 
-      query.attrs.scaler.face_id = type->face_id;
-      query.attrs.scaler.width   = type->width;
-      query.attrs.scaler.height  = type->height;
-      query.attrs.load_flags     = (FT_UInt)type->flags;
-    }
+    query.attrs.scaler.face_id = type->face_id;
+    query.attrs.scaler.width   = type->width;
+    query.attrs.scaler.height  = type->height;
+    query.attrs.load_flags     = (FT_UInt)type->flags;
 
     query.attrs.scaler.pixel = 1;
     query.attrs.scaler.x_res = 0;  /* make compilers happy */
@@ -360,10 +360,10 @@
     FTC_BasicQueryRec  query;
     FTC_Node           node = 0; /* make compiler happy */
     FT_Error           error;
-    FT_PtrDist         hash;
+    FT_Offset          hash;
 
 
-    /* some argument checks are delayed to FTC_Cache_Lookup */
+    /* some argument checks are delayed to `FTC_Cache_Lookup' */
     if ( !aglyph || !scaler )
     {
       error = FT_THROW( Invalid_Argument );
@@ -374,12 +374,11 @@
     if ( anode )
       *anode  = NULL;
 
-    /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */
+    /* `FT_Load_Glyph' and `FT_Load_Char' take FT_UInt flags */
     if ( load_flags > FT_UINT_MAX )
-    {
-      FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));
-      FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) ));
-    }
+      FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
+                  " higher bits in load_flags 0x%x are dropped\n",
+                  load_flags & ~((FT_ULong)FT_UINT_MAX) ));
 
     query.attrs.scaler     = scaler[0];
     query.attrs.load_flags = (FT_UInt)load_flags;
@@ -471,30 +470,27 @@
     FT_Error           error;
     FTC_BasicQueryRec  query;
     FTC_Node           node = 0; /* make compiler happy */
-    FT_PtrDist         hash;
+    FT_Offset          hash;
 
 
     if ( anode )
       *anode = NULL;
 
-    /* other argument checks delayed to FTC_Cache_Lookup */
+    /* other argument checks delayed to `FTC_Cache_Lookup' */
     if ( !ansbit )
       return FT_THROW( Invalid_Argument );
 
     *ansbit = NULL;
 
-    {
-      if ( (FT_ULong)(type->flags - FT_INT_MIN) > FT_UINT_MAX )
-      {
-        FT_TRACE1(( "FTC_ImageCache_Lookup: higher bits in load_flags" ));
-        FT_TRACE1(( "0x%x are dropped\n", (type->flags & ~((FT_ULong)FT_UINT_MAX)) ));
-      }
+    if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX )
+      FT_TRACE1(( "FTC_ImageCache_Lookup:"
+                  " higher bits in load_flags 0x%x are dropped\n",
+                  (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) ));
 
-      query.attrs.scaler.face_id = type->face_id;
-      query.attrs.scaler.width   = type->width;
-      query.attrs.scaler.height  = type->height;
-      query.attrs.load_flags     = (FT_UInt)type->flags;
-    }
+    query.attrs.scaler.face_id = type->face_id;
+    query.attrs.scaler.width   = type->width;
+    query.attrs.scaler.height  = type->height;
+    query.attrs.load_flags     = (FT_UInt)type->flags;
 
     query.attrs.scaler.pixel = 1;
     query.attrs.scaler.x_res = 0;  /* make compilers happy */
@@ -549,24 +545,23 @@
     FT_Error           error;
     FTC_BasicQueryRec  query;
     FTC_Node           node = 0; /* make compiler happy */
-    FT_PtrDist         hash;
+    FT_Offset          hash;
 
 
     if ( anode )
         *anode = NULL;
 
-    /* other argument checks delayed to FTC_Cache_Lookup */
+    /* other argument checks delayed to `FTC_Cache_Lookup' */
     if ( !ansbit || !scaler )
         return FT_THROW( Invalid_Argument );
 
     *ansbit = NULL;
 
-    /* FT_Load_Glyph(), FT_Load_Char() take FT_UInt flags */
+    /* `FT_Load_Glyph' and `FT_Load_Char' take FT_UInt flags */
     if ( load_flags > FT_UINT_MAX )
-    {
-      FT_TRACE1(( "FTC_ImageCache_LookupScaler: higher bits in load_flags" ));
-      FT_TRACE1(( "0x%x are dropped\n", (load_flags & ~((FT_ULong)FT_UINT_MAX)) ));
-    }
+      FT_TRACE1(( "FTC_ImageCache_LookupScaler:"
+                  " higher bits in load_flags 0x%x are dropped\n",
+                  load_flags & ~((FT_ULong)FT_UINT_MAX) ));
 
     query.attrs.scaler     = scaler[0];
     query.attrs.load_flags = (FT_UInt)load_flags;
diff --git a/src/cache/ftccache.c b/src/cache/ftccache.c
index f20dd45..d8c5b99 100644
--- a/src/cache/ftccache.c
+++ b/src/cache/ftccache.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType internal cache interface (body).                        */
 /*                                                                         */
-/*  Copyright 2000-2007, 2009-2011, 2013 by                                */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -88,16 +88,16 @@
    * body for FTC_NODE__TOP_FOR_HASH( cache, hash )
    */
   FT_LOCAL_DEF( FTC_Node* )
-  ftc_get_top_node_for_hash( FTC_Cache   cache,
-                             FT_PtrDist  hash )
+  ftc_get_top_node_for_hash( FTC_Cache  cache,
+                             FT_Offset  hash )
   {
     FTC_Node*  pnode;
-    FT_UInt    idx;
+    FT_Offset  idx;
 
 
-    idx = (FT_UInt)( hash & cache->mask );
+    idx = hash & cache->mask;
     if ( idx < cache->p )
-      idx = (FT_UInt)( hash & ( 2 * cache->mask + 1 ) );
+      idx = hash & ( 2 * cache->mask + 1 );
     pnode = cache->buckets + idx;
     return pnode;
   }
@@ -414,7 +414,7 @@
 
   static void
   ftc_cache_add( FTC_Cache  cache,
-                 FT_PtrDist hash,
+                 FT_Offset  hash,
                  FTC_Node   node )
   {
     node->hash        = hash;
@@ -442,7 +442,7 @@
 
   FT_LOCAL_DEF( FT_Error )
   FTC_Cache_NewNode( FTC_Cache   cache,
-                     FT_PtrDist  hash,
+                     FT_Offset   hash,
                      FT_Pointer  query,
                      FTC_Node   *anode )
   {
@@ -481,7 +481,7 @@
 
   FT_LOCAL_DEF( FT_Error )
   FTC_Cache_Lookup( FTC_Cache   cache,
-                    FT_PtrDist  hash,
+                    FT_Offset   hash,
                     FT_Pointer  query,
                     FTC_Node   *anode )
   {
diff --git a/src/cache/ftccache.h b/src/cache/ftccache.h
index 4155f32..4e17c7a 100644
--- a/src/cache/ftccache.h
+++ b/src/cache/ftccache.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType internal cache interface (specification).                   */
 /*                                                                         */
-/*  Copyright 2000-2007, 2009-2011, 2013 by                                */
+/*  Copyright 2000-2015 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 @@
 
 FT_BEGIN_HEADER
 
-#define _FTC_FACE_ID_HASH( i )                                                \
-          ((FT_PtrDist)(( (FT_PtrDist)(i) >> 3 ) ^ ( (FT_PtrDist)(i) << 7 )))
+#define _FTC_FACE_ID_HASH( i )                                  \
+          ( ( (FT_Offset)(i) >> 3 ) ^ ( (FT_Offset)(i) << 7 ) )
 
   /* handle to cache object */
   typedef struct FTC_CacheRec_*  FTC_Cache;
@@ -59,7 +59,7 @@
   {
     FTC_MruNodeRec  mru;          /* circular mru list pointer           */
     FTC_Node        link;         /* used for hashing                    */
-    FT_PtrDist      hash;         /* used for hashing too                */
+    FT_Offset       hash;         /* used for hashing too                */
     FT_UShort       cache_index;  /* index of cache the node belongs to  */
     FT_Short        ref_count;    /* reference count for this node       */
 
@@ -80,8 +80,8 @@
               : ( ( hash ) &   ( cache )->mask ) ) )
 #else
   FT_LOCAL( FTC_Node* )
-  ftc_get_top_node_for_hash( FTC_Cache   cache,
-                             FT_PtrDist  hash );
+  ftc_get_top_node_for_hash( FTC_Cache  cache,
+                             FT_Offset  hash );
 #define FTC_NODE__TOP_FOR_HASH( cache, hash )            \
         ftc_get_top_node_for_hash( ( cache ), ( hash ) )
 #endif
@@ -179,14 +179,14 @@
 #ifndef FTC_INLINE
   FT_LOCAL( FT_Error )
   FTC_Cache_Lookup( FTC_Cache   cache,
-                    FT_PtrDist  hash,
+                    FT_Offset   hash,
                     FT_Pointer  query,
                     FTC_Node   *anode );
 #endif
 
   FT_LOCAL( FT_Error )
   FTC_Cache_NewNode( FTC_Cache   cache,
-                     FT_PtrDist  hash,
+                     FT_Offset   hash,
                      FT_Pointer  query,
                      FTC_Node   *anode );
 
@@ -211,7 +211,7 @@
   FT_BEGIN_STMNT                                                         \
     FTC_Node             *_bucket, *_pnode, _node;                       \
     FTC_Cache             _cache   = FTC_CACHE(cache);                   \
-    FT_PtrDist            _hash    = (FT_PtrDist)(hash);                 \
+    FT_Offset             _hash    = (FT_Offset)(hash);                  \
     FTC_Node_CompareFunc  _nodcomp = (FTC_Node_CompareFunc)(nodecmp);    \
     FT_Bool               _list_changed = FALSE;                         \
                                                                          \
diff --git a/src/cache/ftccback.h b/src/cache/ftccback.h
index 9528279..b3237d5 100644
--- a/src/cache/ftccback.h
+++ b/src/cache/ftccback.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Callback functions of the caching sub-system (specification only).   */
 /*                                                                         */
-/*  Copyright 2004-2006, 2011, 2013 by                                     */
+/*  Copyright 2004-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cache/ftccmap.c b/src/cache/ftccmap.c
index b2e9609..b826222 100644
--- a/src/cache/ftccmap.c
+++ b/src/cache/ftccmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType CharMap cache (body)                                        */
 /*                                                                         */
-/*  Copyright 2000-2014 by                                                 */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -63,8 +63,6 @@
   } FTC_CMapQueryRec, *FTC_CMapQuery;
 
 #define FTC_CMAP_QUERY( x )  ((FTC_CMapQuery)(x))
-#define FTC_CMAP_QUERY_HASH( x )                                         \
-          FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code )
 
   /* the cmap cache node */
   typedef struct  FTC_CMapNodeRec_
@@ -78,8 +76,6 @@
   } FTC_CMapNodeRec, *FTC_CMapNode;
 
 #define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) )
-#define FTC_CMAP_NODE_HASH( x )                                      \
-          FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first )
 
   /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */
   /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet   */
@@ -242,7 +238,7 @@
     FTC_Node          node;
     FT_Error          error;
     FT_UInt           gindex = 0;
-    FT_PtrDist        hash;
+    FT_Offset         hash;
     FT_Int            no_cmap_change = 0;
 
 
@@ -263,11 +259,14 @@
       return 0;
     }
 
+    if ( !face_id )
+      return 0;
+
     query.face_id    = face_id;
     query.cmap_index = (FT_UInt)cmap_index;
     query.char_code  = char_code;
 
-    hash = FTC_CMAP_HASH( face_id, cmap_index, char_code );
+    hash = FTC_CMAP_HASH( face_id, (FT_UInt)cmap_index, char_code );
 
 #if 1
     FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query,
@@ -301,12 +300,6 @@
       if ( error )
         goto Exit;
 
-#ifdef FT_MAX_CHARMAP_CACHEABLE
-      /* something rotten can happen with rogue clients */
-      if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE )
-        return 0; /* XXX: should return appropriate error */
-#endif
-
       if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps )
       {
         FT_CharMap  old, cmap  = NULL;
diff --git a/src/cache/ftcglyph.c b/src/cache/ftcglyph.c
index 441e177..343b8a7 100644
--- a/src/cache/ftcglyph.c
+++ b/src/cache/ftcglyph.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType Glyph Image (FT_Glyph) cache (body).                        */
 /*                                                                         */
-/*  Copyright 2000-2001, 2003, 2004, 2006, 2009, 2011 by                   */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -185,7 +185,7 @@
 
   FT_LOCAL_DEF( FT_Error )
   FTC_GCache_Lookup( FTC_GCache   cache,
-                     FT_PtrDist   hash,
+                     FT_Offset    hash,
                      FT_UInt      gindex,
                      FTC_GQuery   query,
                      FTC_Node    *anode )
diff --git a/src/cache/ftcglyph.h b/src/cache/ftcglyph.h
index 5fed19c..6cadbe2 100644
--- a/src/cache/ftcglyph.h
+++ b/src/cache/ftcglyph.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType abstract glyph cache (specification).                       */
 /*                                                                         */
-/*  Copyright 2000-2001, 2003, 2004, 2006, 2007, 2011 by                   */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -260,7 +260,7 @@
 #ifndef FTC_INLINE
   FT_LOCAL( FT_Error )
   FTC_GCache_Lookup( FTC_GCache   cache,
-                     FT_PtrDist   hash,
+                     FT_Offset    hash,
                      FT_UInt      gindex,
                      FTC_GQuery   query,
                      FTC_Node    *anode );
diff --git a/src/cache/ftcmanag.h b/src/cache/ftcmanag.h
index 0aec33c..c6787b7 100644
--- a/src/cache/ftcmanag.h
+++ b/src/cache/ftcmanag.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType Cache Manager (specification).                              */
 /*                                                                         */
-/*  Copyright 2000-2001, 2003, 2004, 2006, 2010, 2013 by                   */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cache/ftcmru.c b/src/cache/ftcmru.c
index dc8b4cc..10ce4f3 100644
--- a/src/cache/ftcmru.c
+++ b/src/cache/ftcmru.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType MRU support (body).                                         */
 /*                                                                         */
-/*  Copyright 2003, 2004, 2006, 2009 by                                    */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cache/ftcsbits.c b/src/cache/ftcsbits.c
index 6df1c19..8141719 100644
--- a/src/cache/ftcsbits.c
+++ b/src/cache/ftcsbits.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType sbits manager (body).                                       */
 /*                                                                         */
-/*  Copyright 2000-2006, 2009-2011, 2013 by                                */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -52,7 +52,7 @@
     if ( pitch < 0 )
       pitch = -pitch;
 
-    size = (FT_ULong)( pitch * bitmap->rows );
+    size = (FT_ULong)pitch * bitmap->rows;
 
     if ( !FT_ALLOC( sbit->buffer, size ) )
       FT_MEM_COPY( sbit->buffer, bitmap->buffer, size );
@@ -142,12 +142,12 @@
         goto BadGlyph;
       }
 
-      /* Check that our values fit into 8-bit containers!       */
+      /* Check whether our values fit into 8-bit containers!    */
       /* If this is not the case, our bitmap is too large       */
       /* and we will leave it as `missing' with sbit.buffer = 0 */
 
-#define CHECK_CHAR( d )  ( temp = (FT_Char)d, temp == d )
-#define CHECK_BYTE( d )  ( temp = (FT_Byte)d, temp == d )
+#define CHECK_CHAR( d )  ( temp = (FT_Char)d, (FT_Int) temp == (FT_Int) d )
+#define CHECK_BYTE( d )  ( temp = (FT_Byte)d, (FT_UInt)temp == (FT_UInt)d )
 
       /* horizontal advance in pixels */
       xadvance = ( slot->advance.x + 32 ) >> 6;
@@ -181,7 +181,7 @@
 
       /* now, compute size */
       if ( asize )
-        *asize = FT_ABS( sbit->pitch ) * sbit->height;
+        *asize = (FT_ULong)FT_ABS( sbit->pitch ) * sbit->height;
 
     } /* glyph loading successful */
 
@@ -302,7 +302,7 @@
           pitch = -pitch;
 
         /* add the size of a given glyph image */
-        size += pitch * sbit->height;
+        size += (FT_Offset)pitch * sbit->height;
       }
     }
 
diff --git a/src/cache/ftcsbits.h b/src/cache/ftcsbits.h
index df55dca..5a2fa1a 100644
--- a/src/cache/ftcsbits.h
+++ b/src/cache/ftcsbits.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    A small-bitmap cache (specification).                                */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002, 2003, 2006, 2011 by                         */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cf2arrst.c b/src/cff/cf2arrst.c
index c8d6f13..528b1fa 100644
--- a/src/cff/cf2arrst.c
+++ b/src/cff/cf2arrst.c
@@ -101,7 +101,7 @@
       FT_Error   error  = FT_Err_Ok;        /* for FT_REALLOC */
       FT_Memory  memory = arrstack->memory; /* for FT_REALLOC */
 
-      FT_Long  newSize = (FT_Long)( numElements * arrstack->sizeItem );
+      size_t  newSize = numElements * arrstack->sizeItem;
 
 
       if ( numElements > LONG_MAX / arrstack->sizeItem )
diff --git a/src/cff/cf2fixed.h b/src/cff/cf2fixed.h
index ed1452a..d6d9faf 100644
--- a/src/cff/cf2fixed.h
+++ b/src/cff/cf2fixed.h
@@ -57,22 +57,22 @@
   /* in C 89, left and right shift of negative numbers is  */
   /* implementation specific behaviour in the general case */
 
-#define cf2_intToFixed( i )                                    \
+#define cf2_intToFixed( i )                                              \
           ( (CF2_Fixed)( (FT_UInt32)(i) << 16 ) )
-#define cf2_fixedToInt( x )                                    \
+#define cf2_fixedToInt( x )                                              \
           ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) )
-#define cf2_fixedRound( x )                                    \
-          ( (CF2_Fixed)( ( (x) + 0x8000 ) & 0xFFFF0000L ) )
-#define cf2_floatToFixed( f )                                  \
+#define cf2_fixedRound( x )                                              \
+          ( (CF2_Fixed)( ( (FT_UInt32)(x) + 0x8000U ) & 0xFFFF0000UL ) )
+#define cf2_floatToFixed( f )                                            \
           ( (CF2_Fixed)( (f) * 65536.0 + 0.5 ) )
-#define cf2_fixedAbs( x )                                      \
+#define cf2_fixedAbs( x )                                                \
           ( (x) < 0 ? -(x) : (x) )
-#define cf2_fixedFloor( x )                                    \
-          ( (CF2_Fixed)( (x) & 0xFFFF0000L ) )
-#define cf2_fixedFraction( x )                                 \
+#define cf2_fixedFloor( x )                                              \
+          ( (CF2_Fixed)( (FT_UInt32)(x) & 0xFFFF0000UL ) )
+#define cf2_fixedFraction( x )                                           \
           ( (x) - cf2_fixedFloor( x ) )
-#define cf2_fracToFixed( x )                                   \
-          ( (x) < 0 ? -( ( -(x) + 0x2000 ) >> 14 )             \
+#define cf2_fracToFixed( x )                                             \
+          ( (x) < 0 ? -( ( -(x) + 0x2000 ) >> 14 )                       \
                     :  ( (  (x) + 0x2000 ) >> 14 ) )
 
 
diff --git a/src/cff/cf2font.c b/src/cff/cf2font.c
index 6e99dc2..83fd348 100644
--- a/src/cff/cf2font.c
+++ b/src/cff/cf2font.c
@@ -36,6 +36,9 @@
 /***************************************************************************/
 
 
+#include <ft2build.h>
+#include FT_INTERNAL_CALC_H
+
 #include "cf2ft.h"
 
 #include "cf2glue.h"
@@ -105,6 +108,7 @@
     /* adjusting for emRatio converts darkenAmount to character */
     /* space (font units).                                      */
     CF2_Fixed  stemWidthPer1000, scaledStem;
+    FT_Int     logBase2;
 
 
     *darkenAmount = 0;
@@ -131,25 +135,32 @@
       /* convert from true character space to 1000 unit character space; */
       /* add synthetic emboldening effect                                */
 
-      /* we have to assure that the computation of `scaledStem' */
-      /* and `stemWidthPer1000' don't overflow                  */
+      /* `stemWidthPer1000' will not overflow for a legitimate font      */
 
       stemWidthPer1000 = FT_MulFix( stemWidth + boldenAmount, emRatio );
 
-      if ( emRatio > CF2_FIXED_ONE                          &&
-           stemWidthPer1000 <= ( stemWidth + boldenAmount ) )
-      {
-        stemWidthPer1000 = 0;                      /* to pacify compiler */
-        scaledStem       = cf2_intToFixed( x4 );
-      }
-      else
-      {
-        scaledStem = FT_MulFix( stemWidthPer1000, ppem );
+      /* `scaledStem' can easily overflow, so we must clamp its maximum  */
+      /* value; the test doesn't need to be precise, but must be         */
+      /* conservative.  The clamp value (default 2333) where             */
+      /* `darkenAmount' is zero is well below the overflow value of      */
+      /* 32767.                                                          */
+      /*                                                                 */
+      /* FT_MSB computes the integer part of the base 2 logarithm.  The  */
+      /* number of bits for the product is 1 or 2 more than the sum of   */
+      /* logarithms; remembering that the 16 lowest bits of the fraction */
+      /* are dropped this is correct to within a factor of almost 4.     */
+      /* For example, 0x80.0000 * 0x80.0000 = 0x4000.0000 is 23+23 and   */
+      /* is flagged as possible overflow because 0xFF.FFFF * 0xFF.FFFF = */
+      /* 0xFFFF.FE00 is also 23+23.                                      */
 
-        if ( ppem > CF2_FIXED_ONE           &&
-             scaledStem <= stemWidthPer1000 )
-          scaledStem = cf2_intToFixed( x4 );
-      }
+      logBase2 = FT_MSB( (FT_UInt32)stemWidthPer1000 ) +
+                   FT_MSB( (FT_UInt32)ppem );
+
+      if ( logBase2 >= 46 )
+        /* possible overflow */
+        scaledStem = cf2_intToFixed( x4 );
+      else
+        scaledStem = FT_MulFix( stemWidthPer1000, ppem );
 
       /* now apply the darkening parameters */
 
diff --git a/src/cff/cf2font.h b/src/cff/cf2font.h
index d8860ce..86cf02f 100644
--- a/src/cff/cf2font.h
+++ b/src/cff/cf2font.h
@@ -48,7 +48,12 @@
 
 
 #define CF2_OPERAND_STACK_SIZE  48
-#define CF2_MAX_SUBR            10 /* maximum subroutine nesting */
+#define CF2_MAX_SUBR            16 /* maximum subroutine nesting;         */
+                                   /* only 10 are allowed but there exist */
+                                   /* fonts like `HiraKakuProN-W3.ttf'    */
+                                   /* (Hiragino Kaku Gothic ProN W3;      */
+                                   /* 8.2d6e1; 2014-12-19) that exceed    */
+                                   /* this limit                          */
 
 
   /* typedef is in `cf2glue.h' */
diff --git a/src/cff/cf2ft.c b/src/cff/cf2ft.c
index cb8d31c..d2544a2 100644
--- a/src/cff/cf2ft.c
+++ b/src/cff/cf2ft.c
@@ -142,6 +142,8 @@
   cf2_builder_lineTo( CF2_OutlineCallbacks      callbacks,
                       const CF2_CallbackParams  params )
   {
+    FT_Error  error;
+
     /* downcast the object pointer */
     CF2_Outline   outline = (CF2_Outline)callbacks;
     CFF_Builder*  builder;
@@ -156,15 +158,27 @@
     {
       /* record the move before the line; also check points and set */
       /* `path_begun'                                               */
-      cff_builder_start_point( builder,
-                               params->pt0.x,
-                               params->pt0.y );
+      error = cff_builder_start_point( builder,
+                                       params->pt0.x,
+                                       params->pt0.y );
+      if ( error )
+      {
+        if ( !*callbacks->error )
+          *callbacks->error =  error;
+        return;
+      }
     }
 
     /* `cff_builder_add_point1' includes a check_points call for one point */
-    cff_builder_add_point1( builder,
-                            params->pt1.x,
-                            params->pt1.y );
+    error = cff_builder_add_point1( builder,
+                                    params->pt1.x,
+                                    params->pt1.y );
+    if ( error )
+    {
+      if ( !*callbacks->error )
+        *callbacks->error =  error;
+      return;
+    }
   }
 
 
@@ -172,6 +186,8 @@
   cf2_builder_cubeTo( CF2_OutlineCallbacks      callbacks,
                       const CF2_CallbackParams  params )
   {
+    FT_Error  error;
+
     /* downcast the object pointer */
     CF2_Outline   outline = (CF2_Outline)callbacks;
     CFF_Builder*  builder;
@@ -186,13 +202,25 @@
     {
       /* record the move before the line; also check points and set */
       /* `path_begun'                                               */
-      cff_builder_start_point( builder,
-                               params->pt0.x,
-                               params->pt0.y );
+      error = cff_builder_start_point( builder,
+                                       params->pt0.x,
+                                       params->pt0.y );
+      if ( error )
+      {
+        if ( !*callbacks->error )
+          *callbacks->error =  error;
+        return;
+      }
     }
 
     /* prepare room for 3 points: 2 off-curve, 1 on-curve */
-    cff_check_points( builder, 3 );
+    error = cff_check_points( builder, 3 );
+    if ( error )
+    {
+      if ( !*callbacks->error )
+        *callbacks->error =  error;
+      return;
+    }
 
     cff_builder_add_point( builder,
                            params->pt1.x,
@@ -523,7 +551,7 @@
 
     FT_ZERO( buf );
 
-    idx += decoder->globals_bias;
+    idx += (CF2_UInt)decoder->globals_bias;
     if ( idx >= decoder->num_globals )
       return TRUE;     /* error */
 
@@ -541,7 +569,7 @@
   /* used for seac component                           */
   FT_LOCAL_DEF( FT_Error )
   cf2_getSeacComponent( CFF_Decoder*  decoder,
-                        CF2_UInt      code,
+                        CF2_Int       code,
                         CF2_Buffer    buf )
   {
     CF2_Int   gid;
@@ -554,12 +582,21 @@
 
     FT_ZERO( buf );
 
-    gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code );
-    if ( gid < 0 )
-      return FT_THROW( Invalid_Glyph_Format );
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+    /* Incremental fonts don't necessarily have valid charsets.        */
+    /* They use the character code, not the glyph index, in this case. */
+    if ( decoder->builder.face->root.internal->incremental_interface )
+      gid = code;
+    else
+#endif /* FT_CONFIG_OPTION_INCREMENTAL */
+    {
+      gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code );
+      if ( gid < 0 )
+        return FT_THROW( Invalid_Glyph_Format );
+    }
 
     error = cff_get_glyph_data( decoder->builder.face,
-                                gid,
+                                (CF2_UInt)gid,
                                 &charstring,
                                 &len );
     /* TODO: for now, just pass the FreeType error through */
@@ -598,7 +635,7 @@
 
     FT_ZERO( buf );
 
-    idx += decoder->locals_bias;
+    idx += (CF2_UInt)decoder->locals_bias;
     if ( idx >= decoder->num_locals )
       return TRUE;     /* error */
 
diff --git a/src/cff/cf2ft.h b/src/cff/cf2ft.h
index 731da3c..3073df3 100644
--- a/src/cff/cf2ft.h
+++ b/src/cff/cf2ft.h
@@ -103,7 +103,7 @@
                               CF2_Buffer    buf );
   FT_LOCAL( FT_Error )
   cf2_getSeacComponent( CFF_Decoder*  decoder,
-                        CF2_UInt      code,
+                        CF2_Int       code,
                         CF2_Buffer    buf );
   FT_LOCAL( void )
   cf2_freeSeacComponent( CFF_Decoder*  decoder,
diff --git a/src/cff/cf2hints.c b/src/cff/cf2hints.c
index 81049f4..0e27000 100644
--- a/src/cff/cf2hints.c
+++ b/src/cff/cf2hints.c
@@ -304,9 +304,6 @@
   cf2_hintmap_map( CF2_HintMap  hintmap,
                    CF2_Fixed    csCoord )
   {
-    FT_ASSERT( hintmap->isValid );  /* must call Build before Map */
-    FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES );
-
     if ( hintmap->count == 0 || ! hintmap->hinted )
     {
       /* there are no hints; use uniform scale and zero offset */
@@ -317,6 +314,7 @@
       /* start linear search from last hit */
       CF2_UInt  i = hintmap->lastIndex;
 
+      FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES );
 
       /* search up */
       while ( i < hintmap->count - 1                  &&
@@ -699,10 +697,10 @@
 
     /* make room to insert */
     {
-      CF2_Int  iSrc = hintmap->count - 1;
-      CF2_Int  iDst = isPair ? hintmap->count + 1 : hintmap->count;
+      CF2_UInt  iSrc = hintmap->count - 1;
+      CF2_UInt  iDst = isPair ? hintmap->count + 1 : hintmap->count;
 
-      CF2_Int  count = hintmap->count - indexInsert;
+      CF2_UInt  count = hintmap->count - indexInsert;
 
 
       if ( iDst >= CF2_MAX_HINT_EDGES )
@@ -794,9 +792,12 @@
     maskPtr      = cf2_hintmask_getMaskPtr( &tempHintMask );
 
     /* use the hStem hints only, which are first in the mask */
-    /* TODO: compare this to cffhintmaskGetBitCount */
     bitCount = cf2_arrstack_size( hStemHintArray );
 
+    /* Defense-in-depth.  Should never return here. */
+    if ( bitCount > hintMask->bitCount )
+        return;
+
     /* synthetic embox hints get highest priority */
     if ( font->blues.doEmBoxHints )
     {
@@ -1691,7 +1692,8 @@
 
     if ( glyphpath->elemIsQueued )
     {
-      FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) );
+      FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ||
+                 glyphpath->hintMap.count == 0              );
 
       cf2_glyphpath_pushPrevElem( glyphpath,
                                   &glyphpath->hintMap,
@@ -1777,7 +1779,8 @@
 
     if ( glyphpath->elemIsQueued )
     {
-      FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) );
+      FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ||
+                 glyphpath->hintMap.count == 0              );
 
       cf2_glyphpath_pushPrevElem( glyphpath,
                                   &glyphpath->hintMap,
diff --git a/src/cff/cf2intrp.c b/src/cff/cf2intrp.c
index 5610917..537e060 100644
--- a/src/cff/cf2intrp.c
+++ b/src/cff/cf2intrp.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Adobe's CFF Interpreter (body).                                      */
 /*                                                                         */
-/*  Copyright 2007-2013 Adobe Systems Incorporated.                        */
+/*  Copyright 2007-2014 Adobe Systems Incorporated.                        */
 /*                                                                         */
 /*  This software, and all works of authorship, whether in source or       */
 /*  object code form as indicated by the copyright notice(s) included      */
@@ -43,6 +43,7 @@
 #include "cf2font.h"
 #include "cf2stack.h"
 #include "cf2hints.h"
+#include "cf2intrp.h"
 
 #include "cf2error.h"
 
@@ -593,8 +594,11 @@
 
         /* never add hints after the mask is computed */
         if ( cf2_hintmask_isValid( &hintMask ) )
+        {
           FT_TRACE4(( "cf2_interpT2CharString:"
                       " invalid horizontal hint mask\n" ));
+          break;
+        }
 
         cf2_doStems( font,
                      opStack,
@@ -614,8 +618,11 @@
 
         /* never add hints after the mask is computed */
         if ( cf2_hintmask_isValid( &hintMask ) )
+        {
           FT_TRACE4(( "cf2_interpT2CharString:"
                       " invalid vertical hint mask\n" ));
+          break;
+        }
 
         cf2_doStems( font,
                      opStack,
@@ -754,16 +761,19 @@
 
           /* push our current CFF charstring region on subrStack */
           charstring = (CF2_Buffer)
-                         cf2_arrstack_getPointer( &subrStack,
-                                                  charstringIndex + 1 );
+                         cf2_arrstack_getPointer(
+                           &subrStack,
+                           (size_t)charstringIndex + 1 );
 
           /* set up the new CFF region and pointer */
-          subrIndex = cf2_stack_popInt( opStack );
+          subrIndex = (CF2_UInt)cf2_stack_popInt( opStack );
 
           switch ( op1 )
           {
           case cf2_cmdCALLGSUBR:
-            FT_TRACE4(( "(%d)\n", subrIndex + decoder->globals_bias ));
+            FT_TRACE4(( " (idx %d, entering level %d)\n",
+                        subrIndex + (CF2_UInt)decoder->globals_bias,
+                        charstringIndex + 1 ));
 
             if ( cf2_initGlobalRegionBuffer( decoder,
                                              subrIndex,
@@ -776,7 +786,9 @@
 
           default:
             /* cf2_cmdCALLSUBR */
-            FT_TRACE4(( "(%d)\n", subrIndex + decoder->locals_bias ));
+            FT_TRACE4(( " (idx %d, entering level %d)\n",
+                        subrIndex + (CF2_UInt)decoder->locals_bias,
+                        charstringIndex + 1 ));
 
             if ( cf2_initLocalRegionBuffer( decoder,
                                             subrIndex,
@@ -792,7 +804,7 @@
         continue; /* do not clear the stack */
 
       case cf2_cmdRETURN:
-        FT_TRACE4(( " return\n" ));
+        FT_TRACE4(( " return (leaving level %d)\n", charstringIndex ));
 
         if ( charstringIndex < 1 )
         {
@@ -803,8 +815,9 @@
 
         /* restore position in previous charstring */
         charstring = (CF2_Buffer)
-                       cf2_arrstack_getPointer( &subrStack,
-                                                --charstringIndex );
+                       cf2_arrstack_getPointer(
+                         &subrStack,
+                         (CF2_UInt)--charstringIndex );
         continue;     /* do not clear the stack */
 
       case cf2_cmdESC:
@@ -1082,8 +1095,8 @@
           /* must be either 4 or 5 --                       */
           /* this is a (deprecated) implied `seac' operator */
 
-          CF2_UInt       achar;
-          CF2_UInt       bchar;
+          CF2_Int        achar;
+          CF2_Int        bchar;
           CF2_BufferRec  component;
           CF2_Fixed      dummyWidth;   /* ignore component width */
           FT_Error       error2;
@@ -1141,15 +1154,16 @@
         /* `cf2_hintmask_read' (which also traces the mask bytes) */
         FT_TRACE4(( op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" ));
 
-        /* if there are arguments on the stack, there this is an */
-        /* implied cf2_cmdVSTEMHM                                */
-        if ( cf2_stack_count( opStack ) != 0 )
+        /* never add hints after the mask is computed */
+        if ( cf2_stack_count( opStack ) > 1    &&
+             cf2_hintmask_isValid( &hintMask ) )
         {
-          /* never add hints after the mask is computed */
-          if ( cf2_hintmask_isValid( &hintMask ) )
-            FT_TRACE4(( "cf2_interpT2CharString: invalid hint mask\n" ));
+          FT_TRACE4(( "cf2_interpT2CharString: invalid hint mask\n" ));
+          break;
         }
 
+        /* if there are arguments on the stack, there this is an */
+        /* implied cf2_cmdVSTEMHM                                */
         cf2_doStems( font,
                      opStack,
                      &vStemHintArray,
@@ -1284,10 +1298,16 @@
 
       case cf2_cmdVVCURVETO:
         {
-          CF2_UInt  count = cf2_stack_count( opStack );
+          CF2_UInt  count, count1 = cf2_stack_count( opStack );
           CF2_UInt  index = 0;
 
 
+          /* if `cf2_stack_count' isn't of the form 4n or 4n+1, */
+          /* we enforce it by clearing the second bit           */
+          /* (and sorting the stack indexing to suit)           */
+          count  = count1 & ~2;
+          index += count1 - count;
+
           FT_TRACE4(( " vvcurveto\n" ));
 
           while ( index < count )
@@ -1323,10 +1343,16 @@
 
       case cf2_cmdHHCURVETO:
         {
-          CF2_UInt  count = cf2_stack_count( opStack );
+          CF2_UInt  count, count1 = cf2_stack_count( opStack );
           CF2_UInt  index = 0;
 
 
+          /* if `cf2_stack_count' isn't of the form 4n or 4n+1, */
+          /* we enforce it by clearing the second bit           */
+          /* (and sorting the stack indexing to suit)           */
+          count  = count1 & ~2;
+          index += count1 - count;
+
           FT_TRACE4(( " hhcurveto\n" ));
 
           while ( index < count )
@@ -1363,12 +1389,19 @@
       case cf2_cmdVHCURVETO:
       case cf2_cmdHVCURVETO:
         {
-          CF2_UInt  count = cf2_stack_count( opStack );
+          CF2_UInt  count, count1 = cf2_stack_count( opStack );
           CF2_UInt  index = 0;
 
           FT_Bool  alternate = op1 == cf2_cmdHVCURVETO;
 
 
+          /* if `cf2_stack_count' isn't of the form 8n, 8n+1, */
+          /* 8n+4, or 8n+5, we enforce it by clearing the     */
+          /* second bit                                       */
+          /* (and sorting the stack indexing to suit)         */
+          count  = count1 & ~2;
+          index += count1 - count;
+
           FT_TRACE4(( alternate ? " hvcurveto\n" : " vhcurveto\n" ));
 
           while ( index < count )
diff --git a/src/cff/cff.c b/src/cff/cff.c
index c3840b5..bb2cfb5 100644
--- a/src/cff/cff.c
+++ b/src/cff/cff.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType OpenType driver component (body only).                      */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2013 by                                     */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cffcmap.c b/src/cff/cffcmap.c
index f6e03c6..e7538e9 100644
--- a/src/cff/cffcmap.c
+++ b/src/cff/cffcmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF character mapping table (cmap) support (body).                   */
 /*                                                                         */
-/*  Copyright 2002-2007, 2010, 2013 by                                     */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -33,12 +33,15 @@
   /*************************************************************************/
 
   FT_CALLBACK_DEF( FT_Error )
-  cff_cmap_encoding_init( CFF_CMapStd  cmap )
+  cff_cmap_encoding_init( CFF_CMapStd  cmap,
+                          FT_Pointer   pointer )
   {
     TT_Face       face     = (TT_Face)FT_CMAP_FACE( cmap );
     CFF_Font      cff      = (CFF_Font)face->extra.data;
     CFF_Encoding  encoding = &cff->encoding;
 
+    FT_UNUSED( pointer );
+
 
     cmap->gids  = encoding->codes;
 
@@ -135,7 +138,8 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  cff_cmap_unicode_init( PS_Unicodes  unicodes )
+  cff_cmap_unicode_init( PS_Unicodes  unicodes,
+                         FT_Pointer   pointer )
   {
     TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
     FT_Memory           memory  = FT_FACE_MEMORY( face );
@@ -143,6 +147,8 @@
     CFF_Charset         charset = &cff->charset;
     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)cff->psnames;
 
+    FT_UNUSED( pointer );
+
 
     /* can't build Unicode map for CID-keyed font */
     /* because we don't know glyph names.         */
diff --git a/src/cff/cffcmap.h b/src/cff/cffcmap.h
index 3f7f67b..6eaed63 100644
--- a/src/cff/cffcmap.h
+++ b/src/cff/cffcmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF character mapping table (cmap) support (specification).          */
 /*                                                                         */
-/*  Copyright 2002, 2003, 2006 by                                          */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index dde7d44..a718b7a 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType font driver implementation (body).                          */
 /*                                                                         */
-/*  Copyright 1996-2013 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -35,7 +35,7 @@
 #include "cfferrs.h"
 #include "cffpic.h"
 
-#include FT_SERVICE_XFREE86_NAME_H
+#include FT_SERVICE_FONT_FORMAT_H
 #include FT_SERVICE_GLYPH_DICT_H
 #include FT_SERVICE_PROPERTIES_H
 #include FT_CFF_DRIVER_H
@@ -64,11 +64,6 @@
   /*************************************************************************/
 
 
-#undef  PAIR_TAG
-#define PAIR_TAG( left, right )  ( ( (FT_ULong)left << 16 ) | \
-                                     (FT_ULong)right        )
-
-
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -121,9 +116,6 @@
   }
 
 
-#undef PAIR_TAG
-
-
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -203,6 +195,68 @@
     FT_GlyphSlot  slot  = face->glyph;
 
 
+    if ( FT_IS_SFNT( face ) )
+    {
+      /* OpenType 1.7 mandates that the data from `hmtx' table be used; */
+      /* it is no longer necessary that those values are identical to   */
+      /* the values in the `CFF' table                                  */
+
+      TT_Face   ttface = (TT_Face)face;
+      FT_Short  dummy;
+
+
+      if ( flags & FT_LOAD_VERTICAL_LAYOUT )
+      {
+        /* 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' */
+        /* table)                                                   */
+        if ( !ttface->vertical_info )
+          goto Missing_Table;
+
+        for ( nn = 0; nn < count; nn++ )
+        {
+          FT_UShort  ah;
+
+
+          ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface,
+                                                       1,
+                                                       start + nn,
+                                                       &dummy,
+                                                       &ah );
+
+          FT_TRACE5(( "  idx %d: advance height %d font units\n",
+                      start + nn, ah ));
+          advances[nn] = ah;
+        }
+      }
+      else
+      {
+        /* check whether we have data from the `hmtx' table at all */
+        if ( !ttface->horizontal.number_Of_HMetrics )
+          goto Missing_Table;
+
+        for ( nn = 0; nn < count; nn++ )
+        {
+          FT_UShort  aw;
+
+
+          ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface,
+                                                       0,
+                                                       start + nn,
+                                                       &dummy,
+                                                       &aw );
+
+          FT_TRACE5(( "  idx %d: advance width %d font units\n",
+                      start + nn, aw ));
+          advances[nn] = aw;
+        }
+      }
+
+      return error;
+    }
+
+  Missing_Table:
     flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
 
     for ( nn = 0; nn < count; nn++ )
@@ -352,7 +406,7 @@
       font_info->italic_angle        = dict->italic_angle;
       font_info->is_fixed_pitch      = dict->is_fixed_pitch;
       font_info->underline_position  = (FT_Short)dict->underline_position;
-      font_info->underline_thickness = (FT_Short)dict->underline_thickness;
+      font_info->underline_thickness = (FT_UShort)dict->underline_thickness;
 
       cff->font_info = font_info;
     }
@@ -383,9 +437,27 @@
   static const char*
   cff_get_ps_name( CFF_Face  face )
   {
-    CFF_Font  cff = (CFF_Font)face->extra.data;
+    CFF_Font      cff  = (CFF_Font)face->extra.data;
+    SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
 
 
+    /* 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 )
+    {
+      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 );
+
+
+      if ( service && service->get_ps_font_name )
+        return service->get_ps_font_name( FT_FACE( face ) );
+    }
+
     return (const char*)cff->font_name;
   }
 
@@ -723,7 +795,7 @@
 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
   FT_DEFINE_SERVICEDESCREC7(
     cff_services,
-    FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CFF,
+    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,
     FT_SERVICE_ID_GLYPH_DICT,           &CFF_SERVICE_GLYPH_DICT_GET,
@@ -734,7 +806,7 @@
 #else
   FT_DEFINE_SERVICEDESCREC6(
     cff_services,
-    FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CFF,
+    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,
     FT_SERVICE_ID_TT_CMAP,              &CFF_SERVICE_GET_CMAP_INFO_GET,
@@ -753,7 +825,7 @@
     FT_Module_Interface  result;
 
 
-    /* CFF_SERVICES_GET derefers `library' in PIC mode */
+    /* CFF_SERVICES_GET dereferences `library' in PIC mode */
 #ifdef FT_CONFIG_OPTION_PIC
     if ( !driver )
       return NULL;
diff --git a/src/cff/cffdrivr.h b/src/cff/cffdrivr.h
index 50e8138..9527f5e 100644
--- a/src/cff/cffdrivr.h
+++ b/src/cff/cffdrivr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level OpenType driver interface (specification).                */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002 by                                           */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cfferrs.h b/src/cff/cfferrs.h
index 801d73e..543bdb0 100644
--- a/src/cff/cfferrs.h
+++ b/src/cff/cfferrs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF error codes (specification only).                                */
 /*                                                                         */
-/*  Copyright 2001, 2012 by                                                */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index c8e9f91..43054f8 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType Glyph Loader (body).                                        */
 /*                                                                         */
-/*  Copyright 1996-2013 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -273,8 +273,8 @@
       builder->current = &loader->current.outline;
       FT_GlyphLoader_Rewind( loader );
 
-      builder->hints_globals = 0;
-      builder->hints_funcs   = 0;
+      builder->hints_globals = NULL;
+      builder->hints_funcs   = NULL;
 
       if ( hinting && size )
       {
@@ -646,7 +646,7 @@
     for ( n = 0; n < cff->num_glyphs; n++ )
     {
       if ( cff->charset.sids[n] == glyph_sid )
-        return n;
+        return (FT_Int)n;
     }
 
     return -1;
@@ -672,7 +672,7 @@
 
 
       *pointer = (FT_Byte*)data.pointer;
-      *length = data.length;
+      *length  = (FT_ULong)data.length;
 
       return error;
     }
@@ -703,11 +703,11 @@
     /* callback function.                                     */
     if ( face->root.internal->incremental_interface )
     {
-      FT_Data data;
+      FT_Data  data;
 
 
       data.pointer = *pointer;
-      data.length  = length;
+      data.length  = (FT_Int)length;
 
       face->root.internal->incremental_interface->funcs->free_glyph_data(
         face->root.internal->incremental_interface->object, &data );
@@ -819,7 +819,7 @@
     FT_GlyphLoader_Prepare( builder->loader );
 
     /* First load `bchar' in builder */
-    error = cff_get_glyph_data( face, bchar_index,
+    error = cff_get_glyph_data( face, (FT_UInt)bchar_index,
                                 &charstring, &charstring_len );
     if ( !error )
     {
@@ -849,7 +849,7 @@
     builder->pos_y = ady;
 
     /* Now load `achar' on top of the base outline. */
-    error = cff_get_glyph_data( face, achar_index,
+    error = cff_get_glyph_data( face, (FT_UInt)achar_index,
                                 &charstring, &charstring_len );
     if ( !error )
     {
@@ -922,10 +922,10 @@
     decoder->read_width = 1;
 
     /* compute random seed from stack address of parameter */
-    seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed              ^
-                         (FT_PtrDist)(char*)&decoder           ^
-                         (FT_PtrDist)(char*)&charstring_base ) &
-                         FT_ULONG_MAX ) ;
+    seed = (FT_Fixed)( ( (FT_Offset)(char*)&seed            ^
+                         (FT_Offset)(char*)&decoder         ^
+                         (FT_Offset)(char*)&charstring_base ) &
+                         FT_ULONG_MAX                         );
     seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
     if ( seed == 0 )
       seed = 0x7384;
@@ -1373,12 +1373,12 @@
           {
             if ( op == cff_op_hintmask )
               hinter->hintmask( hinter->hints,
-                                builder->current->n_points,
-                                decoder->num_hints,
+                                (FT_UInt)builder->current->n_points,
+                                (FT_UInt)decoder->num_hints,
                                 ip );
             else
               hinter->counter( hinter->hints,
-                               decoder->num_hints,
+                               (FT_UInt)decoder->num_hints,
                                ip );
           }
 
@@ -1989,23 +1989,22 @@
           }
           else
           {
-            if ( !error )
-              error = FT_Err_Ok;
-
             cff_builder_close_contour( builder );
 
             /* close hints recording session */
             if ( hinter )
             {
               if ( hinter->close( hinter->hints,
-                                  builder->current->n_points ) )
+                                  (FT_UInt)builder->current->n_points ) )
                 goto Syntax_Error;
 
               /* apply hints to the loaded glyph outline now */
-              hinter->apply( hinter->hints,
-                             builder->current,
-                             (PSH_Globals)builder->hints_globals,
-                             decoder->hint_mode );
+              error = hinter->apply( hinter->hints,
+                                     builder->current,
+                                     (PSH_Globals)builder->hints_globals,
+                                     decoder->hint_mode );
+              if ( error )
+                goto Fail;
             }
 
             /* add current outline to the glyph slot */
@@ -2390,7 +2389,9 @@
                                       decoder->locals_bias );
 
 
-            FT_TRACE4(( " callsubr(%d)\n", idx ));
+            FT_TRACE4(( " callsubr (idx %d, entering level %d)\n",
+                        idx,
+                        zone - decoder->zones + 1 ));
 
             if ( idx >= decoder->num_locals )
             {
@@ -2432,7 +2433,9 @@
                                       decoder->globals_bias );
 
 
-            FT_TRACE4(( " callgsubr(%d)\n", idx ));
+            FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n",
+                        idx,
+                        zone - decoder->zones + 1 ));
 
             if ( idx >= decoder->num_globals )
             {
@@ -2469,7 +2472,8 @@
           break;
 
         case cff_op_return:
-          FT_TRACE4(( " return\n" ));
+          FT_TRACE4(( " return (leaving level %d)\n",
+                      decoder->zone - decoder->zones ));
 
           if ( decoder->zone <= decoder->zones )
           {
@@ -2670,7 +2674,7 @@
         error = sfnt->load_sbit_image( face,
                                        size->strike_index,
                                        glyph_index,
-                                       (FT_Int)load_flags,
+                                       (FT_UInt)load_flags,
                                        stream,
                                        &glyph->root.bitmap,
                                        &metrics );
@@ -2711,23 +2715,23 @@
 
           /* compute linear advance widths */
 
-          ( (SFNT_Service)face->sfnt )->get_metrics( face, 0,
-                                                     glyph_index,
-                                                     &dummy,
-                                                     &advance );
+          (void)( (SFNT_Service)face->sfnt )->get_metrics( face, 0,
+                                                           glyph_index,
+                                                           &dummy,
+                                                           &advance );
           glyph->root.linearHoriAdvance = advance;
 
           has_vertical_info = FT_BOOL(
                                 face->vertical_info                   &&
                                 face->vertical.number_Of_VMetrics > 0 );
 
-          /* get the vertical metrics from the vtmx table if we have one */
+          /* get the vertical metrics from the vmtx table if we have one */
           if ( has_vertical_info )
           {
-            ( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
-                                                       glyph_index,
-                                                       &dummy,
-                                                       &advance );
+            (void)( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
+                                                             glyph_index,
+                                                             &dummy,
+                                                             &advance );
             glyph->root.linearVertAdvance = advance;
           }
           else
@@ -2758,16 +2762,16 @@
     /* this scaling is only relevant if the PS hinter isn't active */
     if ( cff->num_subfonts )
     {
-      FT_ULong  top_upm, sub_upm;
-      FT_Byte   fd_index = cff_fd_select_get( &cff->fd_select,
-                                              glyph_index );
+      FT_Long  top_upm, sub_upm;
+      FT_Byte  fd_index = cff_fd_select_get( &cff->fd_select,
+                                             glyph_index );
 
 
       if ( fd_index >= cff->num_subfonts )
         fd_index = (FT_Byte)( cff->num_subfonts - 1 );
 
-      top_upm = cff->top_font.font_dict.units_per_em;
-      sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em;
+      top_upm = (FT_Long)cff->top_font.font_dict.units_per_em;
+      sub_upm = (FT_Long)cff->subfonts[fd_index]->font_dict.units_per_em;
 
 
       font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
@@ -2868,7 +2872,7 @@
       /* fonts.                                                       */
       if ( face->root.internal->incremental_interface )
       {
-        glyph->root.control_data = 0;
+        glyph->root.control_data = NULL;
         glyph->root.control_len = 0;
       }
       else
@@ -2885,7 +2889,7 @@
         {
           glyph->root.control_data = csindex->bytes +
                                      csindex->offsets[glyph_index] - 1;
-          glyph->root.control_len  = charstring_len;
+          glyph->root.control_len  = (FT_Long)charstring_len;
         }
       }
 
@@ -2949,15 +2953,33 @@
         FT_Bool            has_vertical_info;
 
 
-        /* copy the _unscaled_ advance width */
-        metrics->horiAdvance                    = decoder.glyph_width;
-        glyph->root.linearHoriAdvance           = decoder.glyph_width;
+        if ( face->horizontal.number_Of_HMetrics )
+        {
+          FT_Short   horiBearingX = 0;
+          FT_UShort  horiAdvance  = 0;
+
+
+          ( (SFNT_Service)face->sfnt )->get_metrics( face, 0,
+                                                     glyph_index,
+                                                     &horiBearingX,
+                                                     &horiAdvance );
+          metrics->horiAdvance          = horiAdvance;
+          metrics->horiBearingX         = horiBearingX;
+          glyph->root.linearHoriAdvance = horiAdvance;
+        }
+        else
+        {
+          /* copy the _unscaled_ advance width */
+          metrics->horiAdvance          = decoder.glyph_width;
+          glyph->root.linearHoriAdvance = decoder.glyph_width;
+        }
+
         glyph->root.internal->glyph_transformed = 0;
 
         has_vertical_info = FT_BOOL( face->vertical_info                   &&
                                      face->vertical.number_Of_VMetrics > 0 );
 
-        /* get the vertical metrics from the vtmx table if we have one */
+        /* get the vertical metrics from the vmtx table if we have one */
         if ( has_vertical_info )
         {
           FT_Short   vertBearingY = 0;
@@ -3042,7 +3064,9 @@
         metrics->width  = cbox.xMax - cbox.xMin;
         metrics->height = cbox.yMax - cbox.yMin;
 
-        metrics->horiBearingX = cbox.xMin;
+        if ( !face->horizontal.number_Of_HMetrics )
+          metrics->horiBearingX = cbox.xMin;
+
         metrics->horiBearingY = cbox.yMax;
 
         if ( has_vertical_info )
diff --git a/src/cff/cffgload.h b/src/cff/cffgload.h
index 41df7db..5f2655f 100644
--- a/src/cff/cffgload.h
+++ b/src/cff/cffgload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType Glyph Loader (specification).                               */
 /*                                                                         */
-/*  Copyright 1996-2004, 2006-2009, 2013 by                                */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -29,7 +29,12 @@
 
 
 #define CFF_MAX_OPERANDS        48
-#define CFF_MAX_SUBRS_CALLS     32
+#define CFF_MAX_SUBRS_CALLS     16  /* maximum subroutine nesting;         */
+                                    /* only 10 are allowed but there exist */
+                                    /* fonts like `HiraKakuProN-W3.ttf'    */
+                                    /* (Hiragino Kaku Gothic ProN W3;      */
+                                    /* 8.2d6e1; 2014-12-19) that exceed    */
+                                    /* this limit                          */
 #define CFF_MAX_TRANS_ELEMENTS  32
 
 
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index d9bec59..fcb7348 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType and CFF data/program tables loader (body).                  */
 /*                                                                         */
-/*  Copyright 1996-2014 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -357,7 +357,7 @@
 
       case 3:
         for ( ; p < p_end; p += 3, poff++ )
-          poff[0] = FT_PEEK_OFF3( p );
+          poff[0] = FT_PEEK_UOFF3( p );
         break;
 
       default:
@@ -809,7 +809,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 = 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;
@@ -1447,7 +1447,7 @@
     FT_ULong         base_offset;
     CFF_FontRecDict  dict;
     CFF_IndexRec     string_index;
-    FT_Int           subfont_index;
+    FT_UInt          subfont_index;
 
 
     FT_ZERO( font );
@@ -1495,9 +1495,9 @@
     if ( pure_cff )
     {
       /* well, we don't really forget the `disabled' fonts... */
-      subfont_index = face_index;
+      subfont_index = (FT_UInt)face_index;
 
-      if ( subfont_index >= (FT_Int)font->name_index.count )
+      if ( subfont_index >= font->name_index.count )
       {
         FT_ERROR(( "cff_font_load:"
                    " invalid subfont index for pure CFF font (%d)\n",
diff --git a/src/cff/cffload.h b/src/cff/cffload.h
index 8049619..459e7b0 100644
--- a/src/cff/cffload.h
+++ b/src/cff/cffload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType & CFF data/program tables loader (specification).           */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2007, 2008, 2010 by                   */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index cac4ac2..4a1ef11 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType objects manager (body).                                     */
 /*                                                                         */
-/*  Copyright 1996-2013 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -226,8 +226,8 @@
       CFF_Font      font     = (CFF_Font)face->extra.data;
       CFF_Internal  internal = (CFF_Internal)size->internal;
 
-      FT_ULong  top_upm  = font->top_font.font_dict.units_per_em;
-      FT_UInt   i;
+      FT_Long  top_upm  = (FT_Long)font->top_font.font_dict.units_per_em;
+      FT_UInt  i;
 
 
       funcs->set_scale( internal->topfont,
@@ -237,7 +237,7 @@
       for ( i = font->num_subfonts; i > 0; i-- )
       {
         CFF_SubFont  sub     = font->subfonts[i - 1];
-        FT_ULong     sub_upm = sub->font_dict.units_per_em;
+        FT_Long      sub_upm = (FT_Long)sub->font_dict.units_per_em;
         FT_Pos       x_scale, y_scale;
 
 
@@ -298,8 +298,8 @@
       CFF_Font      font     = (CFF_Font)cffface->extra.data;
       CFF_Internal  internal = (CFF_Internal)size->internal;
 
-      FT_ULong  top_upm  = font->top_font.font_dict.units_per_em;
-      FT_UInt   i;
+      FT_Long  top_upm  = (FT_Long)font->top_font.font_dict.units_per_em;
+      FT_UInt  i;
 
 
       funcs->set_scale( internal->topfont,
@@ -309,7 +309,7 @@
       for ( i = font->num_subfonts; i > 0; i-- )
       {
         CFF_SubFont  sub     = font->subfonts[i - 1];
-        FT_ULong     sub_upm = sub->font_dict.units_per_em;
+        FT_Long      sub_upm = (FT_Long)sub->font_dict.units_per_em;
         FT_Pos       x_scale, y_scale;
 
 
@@ -342,7 +342,7 @@
   FT_LOCAL_DEF( void )
   cff_slot_done( FT_GlyphSlot  slot )
   {
-    slot->internal->glyph_hints = 0;
+    slot->internal->glyph_hints = NULL;
   }
 
 
@@ -592,7 +592,7 @@
       /* Note that this is only necessary for pure CFF and CEF fonts; */
       /* SFNT based fonts use the `name' table instead.               */
 
-      cffface->num_glyphs = cff->num_glyphs;
+      cffface->num_glyphs = (FT_Long)cff->num_glyphs;
 
       dict = &cff->top_font.font_dict;
 
@@ -646,7 +646,7 @@
 
         if ( temp != 0x10000L )
         {
-          *upm = FT_DivFix( *upm, temp );
+          *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp );
 
           matrix->xx = FT_DivFix( matrix->xx, temp );
           matrix->yx = FT_DivFix( matrix->yx, temp );
@@ -682,7 +682,8 @@
           if ( top->has_font_matrix )
           {
             if ( top->units_per_em > 1 && sub->units_per_em > 1 )
-              scaling = FT_MIN( top->units_per_em, sub->units_per_em );
+              scaling = (FT_Long)FT_MIN( top->units_per_em,
+                                         sub->units_per_em );
             else
               scaling = 1;
 
@@ -693,9 +694,10 @@
                                         &top->font_matrix,
                                         scaling );
 
-            sub->units_per_em = FT_MulDiv( sub->units_per_em,
-                                           top->units_per_em,
-                                           scaling );
+            sub->units_per_em = (FT_ULong)
+                                  FT_MulDiv( (FT_Long)sub->units_per_em,
+                                             (FT_Long)top->units_per_em,
+                                             scaling );
           }
         }
         else
@@ -713,7 +715,7 @@
 
         if ( temp != 0x10000L )
         {
-          *upm = FT_DivFix( *upm, temp );
+          *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp );
 
           matrix->xx = FT_DivFix( matrix->xx, temp );
           matrix->yx = FT_DivFix( matrix->yx, temp );
@@ -733,13 +735,13 @@
 
 
         /* set up num_faces */
-        cffface->num_faces = cff->num_faces;
+        cffface->num_faces = (FT_Long)cff->num_faces;
 
         /* compute number of glyphs */
         if ( dict->cid_registry != 0xFFFFU )
-          cffface->num_glyphs = cff->charset.max_cid + 1;
+          cffface->num_glyphs = (FT_Long)( cff->charset.max_cid + 1 );
         else
-          cffface->num_glyphs = cff->charstrings_index.count;
+          cffface->num_glyphs = (FT_Long)cff->charstrings_index.count;
 
         /* set global bbox, as well as EM size */
         cffface->bbox.xMin =   dict->font_bbox.xMin            >> 16;
@@ -763,7 +765,8 @@
           (FT_Short)( dict->underline_thickness >> 16 );
 
         /* retrieve font family & style name */
-        cffface->family_name = cff_index_get_name( cff, face_index );
+        cffface->family_name = cff_index_get_name( cff,
+                                                   (FT_UInt)face_index );
         if ( cffface->family_name )
         {
           char*  full   = cff_index_get_sid_string( cff,
@@ -943,16 +946,6 @@
         if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )
           goto Exit;
 
-#ifdef FT_MAX_CHARMAP_CACHEABLE
-        if ( nn + 1 > FT_MAX_CHARMAP_CACHEABLE )
-        {
-          FT_ERROR(( "cff_face_init: no Unicode cmap is found, "
-                     "and too many subtables (%d) to add synthesized cmap\n",
-                     nn ));
-          goto Exit;
-        }
-#endif
-
         /* we didn't find a Unicode charmap -- synthesize one */
         cmaprec.face        = cffface;
         cmaprec.platform_id = TT_PLATFORM_MICROSOFT;
@@ -973,15 +966,6 @@
           cffface->charmap = cffface->charmaps[nn];
 
       Skip_Unicode:
-#ifdef FT_MAX_CHARMAP_CACHEABLE
-        if ( nn > FT_MAX_CHARMAP_CACHEABLE )
-        {
-          FT_ERROR(( "cff_face_init: Unicode cmap is found, "
-                     "but too many preceding subtables (%d) to access\n",
-                     nn - 1 ));
-          goto Exit;
-        }
-#endif
         if ( encoding->count > 0 )
         {
           FT_CMap_Class  clazz;
@@ -1055,22 +1039,23 @@
     CFF_Driver  driver = (CFF_Driver)module;
 
 
-    /* set default property values, cf `ftcffdrv.h' */
+    /* set default property values, cf. `ftcffdrv.h' */
 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-    driver->hinting_engine    = FT_CFF_HINTING_FREETYPE;
+    driver->hinting_engine = FT_CFF_HINTING_FREETYPE;
 #else
-    driver->hinting_engine    = FT_CFF_HINTING_ADOBE;
+    driver->hinting_engine = FT_CFF_HINTING_ADOBE;
 #endif
+
     driver->no_stem_darkening = FALSE;
 
-    driver->darken_params[0] =  500;
-    driver->darken_params[1] =  400;
-    driver->darken_params[2] = 1000;
-    driver->darken_params[3] =  275;
-    driver->darken_params[4] = 1667;
-    driver->darken_params[5] =  275;
-    driver->darken_params[6] = 2333;
-    driver->darken_params[7] =    0;
+    driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1;
+    driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1;
+    driver->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2;
+    driver->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2;
+    driver->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3;
+    driver->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3;
+    driver->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4;
+    driver->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4;
 
     return FT_Err_Ok;
   }
diff --git a/src/cff/cffobjs.h b/src/cff/cffobjs.h
index dfbf9a9..3cc9531 100644
--- a/src/cff/cffobjs.h
+++ b/src/cff/cffobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType objects manager (specification).                            */
 /*                                                                         */
-/*  Copyright 1996-2004, 2006-2008, 2013 by                                */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index 91bd532..063b351 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF token stream parser (body)                                       */
 /*                                                                         */
-/*  Copyright 1996-2004, 2007-2014 by                                      */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -129,7 +129,7 @@
                   FT_Long*  scaling )
   {
     FT_Byte*  p = start;
-    FT_UInt   nib;
+    FT_Int    nib;
     FT_UInt   phase;
 
     FT_Long   result, number, exponent;
@@ -166,7 +166,7 @@
       }
 
       /* Get the nibble. */
-      nib   = ( p[0] >> phase ) & 0xF;
+      nib   = (FT_Int)( p[0] >> phase ) & 0xF;
       phase = 4 - phase;
 
       if ( nib == 0xE )
@@ -188,7 +188,7 @@
     }
 
     /* Read fraction part, if any. */
-    if ( nib == 0xa )
+    if ( nib == 0xA )
       for (;;)
       {
         /* If we entered this iteration with phase == 4, we need */
@@ -559,7 +559,7 @@
       offset->x  = cff_parse_fixed_scaled( data++, scaling );
       offset->y  = cff_parse_fixed_scaled( data,   scaling );
 
-      *upm = power_tens[scaling];
+      *upm = (FT_ULong)power_tens[scaling];
 
       FT_TRACE4(( " [%f %f %f %f %f %f]\n",
                   (double)matrix->xx / *upm / 65536,
@@ -617,14 +617,34 @@
 
     if ( parser->top >= parser->stack + 2 )
     {
-      dict->private_size   = cff_parse_num( data++ );
-      dict->private_offset = cff_parse_num( data   );
+      FT_Long  tmp;
+
+
+      tmp = cff_parse_num( data++ );
+      if ( tmp < 0 )
+      {
+        FT_ERROR(( "cff_parse_private_dict: Invalid dictionary size\n" ));
+        error = FT_THROW( Invalid_File_Format );
+        goto Fail;
+      }
+      dict->private_size = (FT_ULong)tmp;
+
+      tmp = cff_parse_num( data );
+      if ( tmp < 0 )
+      {
+        FT_ERROR(( "cff_parse_private_dict: Invalid dictionary offset\n" ));
+        error = FT_THROW( Invalid_File_Format );
+        goto Fail;
+      }
+      dict->private_offset = (FT_ULong)tmp;
+
       FT_TRACE4(( " %lu %lu\n",
                   dict->private_size, dict->private_offset ));
 
       error = FT_Err_Ok;
     }
 
+  Fail:
     return error;
   }
 
diff --git a/src/cff/cffparse.h b/src/cff/cffparse.h
index 61d91ed..8ad02ea 100644
--- a/src/cff/cffparse.h
+++ b/src/cff/cffparse.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF token stream parser (specification)                              */
 /*                                                                         */
-/*  Copyright 1996-2003, 2011 by                                           */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cffpic.c b/src/cff/cffpic.c
index f22e4f0..d40dec5 100644
--- a/src/cff/cffpic.c
+++ b/src/cff/cffpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for cff module.      */
 /*                                                                         */
-/*  Copyright 2009, 2010, 2012, 2013 by                                    */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cffpic.h b/src/cff/cffpic.h
index 50bab4c..a29620e 100644
--- a/src/cff/cffpic.h
+++ b/src/cff/cffpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for cff module.      */
 /*                                                                         */
-/*  Copyright 2009, 2012, 2013 by                                          */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cfftoken.h b/src/cff/cfftoken.h
index bcb4276..5b32076 100644
--- a/src/cff/cfftoken.h
+++ b/src/cff/cfftoken.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF token definitions (specification only).                          */
 /*                                                                         */
-/*  Copyright 1996-2003, 2011 by                                           */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cfftypes.h b/src/cff/cfftypes.h
index 8727446..de8a5ee 100644
--- a/src/cff/cfftypes.h
+++ b/src/cff/cfftypes.h
@@ -5,7 +5,7 @@
 /*    Basic OpenType/CFF type definitions and interface (specification     */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 1996-2003, 2006-2008, 2010-2011, 2013 by                     */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/gzip/ftgzip.c b/src/gzip/ftgzip.c
index 2c60b6c..879eb88 100644
--- a/src/gzip/ftgzip.c
+++ b/src/gzip/ftgzip.c
@@ -8,7 +8,7 @@
 /*  parse compressed PCF fonts, as found with many X11 server              */
 /*  distributions.                                                         */
 /*                                                                         */
-/*  Copyright 2002-2006, 2009-2013 by                                      */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -58,7 +58,6 @@
  /* conflicts when a program is linked with both FreeType and the    */
  /* original ZLib.                                                   */
 
-#define NO_DUMMY_DECL
 #ifndef USE_ZLIB_ZCALLOC
 #define MY_ZCALLOC /* prevent all zcalloc() & zfree() in zutils.c */
 #endif
@@ -208,8 +207,8 @@
 
     /* head[0] && head[1] are the magic numbers;    */
     /* head[2] is the method, and head[3] the flags */
-    if ( head[0] != 0x1f              ||
-         head[1] != 0x8b              ||
+    if ( head[0] != 0x1F              ||
+         head[1] != 0x8B              ||
          head[2] != Z_DEFLATED        ||
         (head[3] & FT_GZIP_RESERVED)  )
     {
@@ -603,10 +602,18 @@
                       FT_Stream  source )
   {
     FT_Error     error;
-    FT_Memory    memory = source->memory;
+    FT_Memory    memory;
     FT_GZipFile  zip = NULL;
 
 
+    if ( !stream || !source )
+    {
+      error = FT_THROW( Invalid_Stream_Handle );
+      goto Exit;
+    }
+
+    memory = source->memory;
+
     /*
      *  check the header right now; this prevents allocating un-necessary
      *  objects when we don't need them
@@ -700,6 +707,11 @@
     int       err;
 
 
+    /* check for `input' delayed to `inflate' */
+
+    if ( !memory || ! output_len || !output )
+      return FT_THROW( Invalid_Argument );
+
     /* this function is modeled after zlib's `uncompress' function */
 
     stream.next_in  = (Bytef*)input;
diff --git a/src/gzip/inftrees.c b/src/gzip/inftrees.c
index ef53652..56f52b1 100644
--- a/src/gzip/inftrees.c
+++ b/src/gzip/inftrees.c
@@ -115,16 +115,16 @@
   uInt f;                       /* i repeats in table every f entries */
   int g;                        /* maximum code length */
   int h;                        /* table level */
-  register uInt i;              /* counter, current code */
-  register uInt j;              /* counter */
-  register int k;               /* number of bits in current code */
+  uInt i;                       /* counter, current code */
+  uInt j;                       /* counter */
+  int k;                        /* number of bits in current code */
   int l;                        /* bits per table (returned in m) */
   uInt mask;                    /* (1 << w) - 1, to avoid cc -O bug on HP */
-  register uIntf *p;            /* pointer into c[], b[], or v[] */
+  uIntf *p;                     /* pointer into c[], b[], or v[] */
   inflate_huft *q;              /* points to current table */
   struct inflate_huft_s r;      /* table entry for structure assignment */
   inflate_huft *u[BMAX];        /* table stack */
-  register int w;               /* bits before this table == (l * h) */
+  int w;                        /* bits before this table == (l * h) */
   uInt x[BMAX+1];               /* bit offsets, then code stack */
   uIntf *xp;                    /* pointer into x */
   int y;                        /* number of dummy codes added */
diff --git a/src/pfr/pfrload.c b/src/pfr/pfrload.c
index 97c130a..ec7311d 100644
--- a/src/pfr/pfrload.c
+++ b/src/pfr/pfrload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType PFR loader (body).                                          */
 /*                                                                         */
-/*  Copyright 2002-2005, 2007, 2009, 2010, 2013, 2014 by                   */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -179,7 +179,7 @@
     if ( header->signature  != 0x50465230L ||   /* "PFR0" */
          header->version     > 4           ||
          header->header_size < 58          ||
-         header->signature2 != 0x0d0a      )    /* CR/LF  */
+         header->signature2 != 0x0D0A      )    /* CR/LF  */
     {
       result = 0;
     }
@@ -199,7 +199,7 @@
   FT_LOCAL_DEF( FT_Error )
   pfr_log_font_count( FT_Stream  stream,
                       FT_UInt32  section_offset,
-                      FT_UInt   *acount )
+                      FT_Long   *acount )
   {
     FT_Error  error;
     FT_UInt   count;
@@ -212,7 +212,7 @@
     result = count;
 
   Exit:
-    *acount = result;
+    *acount = (FT_Long)result;
     return error;
   }
 
@@ -449,9 +449,9 @@
                                FT_Byte*     limit,
                                PFR_PhyFont  phy_font )
   {
-    FT_Error    error  = FT_Err_Ok;
-    FT_Memory   memory = phy_font->memory;
-    FT_PtrDist  len    = limit - p;
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = phy_font->memory;
+    FT_UInt    len    = (FT_UInt)( limit - p );
 
 
     if ( phy_font->font_id != NULL )
@@ -535,7 +535,8 @@
     item->pair_count = PFR_NEXT_BYTE( p );
     item->base_adj   = PFR_NEXT_SHORT( p );
     item->flags      = PFR_NEXT_BYTE( p );
-    item->offset     = phy_font->offset + ( p - phy_font->cursor );
+    item->offset     = phy_font->offset +
+                       (FT_Offset)( p - phy_font->cursor );
 
 #ifndef PFR_CONFIG_NO_CHECKS
     item->pair_size = 3;
@@ -864,7 +865,7 @@
 
 
       phy_font->num_chars    = count = PFR_NEXT_USHORT( p );
-      phy_font->chars_offset = offset + ( p - stream->cursor );
+      phy_font->chars_offset = offset + (FT_Offset)( p - stream->cursor );
 
       if ( FT_NEW_ARRAY( phy_font->chars, count ) )
         goto Fail;
@@ -898,7 +899,7 @@
 
         cur->advance   = ( flags & PFR_PHY_PROPORTIONAL )
                          ? PFR_NEXT_SHORT( p )
-                         : (FT_Int) phy_font->standard_advance;
+                         : phy_font->standard_advance;
 
 #if 0
         cur->ascii     = ( flags & PFR_PHY_ASCII_CODE )
diff --git a/src/psaux/afmparse.c b/src/psaux/afmparse.c
index 6a40e11..3ad44ec 100644
--- a/src/psaux/afmparse.c
+++ b/src/psaux/afmparse.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    AFM parser (body).                                                   */
 /*                                                                         */
-/*  Copyright 2006-2010, 2012, 2013 by                                     */
+/*  Copyright 2006-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -75,8 +75,8 @@
 #define AFM_STREAM_KEY_BEGIN( stream )    \
           (char*)( (stream)->cursor - 1 )
 
-#define AFM_STREAM_KEY_LEN( stream, key )       \
-          ( (char*)(stream)->cursor - key - 1 )
+#define AFM_STREAM_KEY_LEN( stream, key )           \
+          (FT_Offset)( (char*)(stream)->cursor - key - 1 )
 
 #define AFM_STATUS_EOC( stream ) \
           ( (stream)->status >= AFM_STREAM_STATUS_EOC )
@@ -369,11 +369,11 @@
   FT_LOCAL_DEF( FT_Int )
   afm_parser_read_vals( AFM_Parser  parser,
                         AFM_Value   vals,
-                        FT_UInt     n )
+                        FT_Int      n )
   {
     AFM_Stream  stream = parser->stream;
     char*       str;
-    FT_UInt     i;
+    FT_Int      i;
 
 
     if ( n > AFM_MAX_ARGUMENTS )
@@ -446,7 +446,7 @@
                        FT_Offset*  len )
   {
     AFM_Stream  stream = parser->stream;
-    char*       key    = 0;  /* make stupid compiler happy */
+    char*       key    = NULL;  /* make stupid compiler happy */
 
 
     if ( line )
@@ -562,7 +562,7 @@
   }
 
 
-  FT_LOCAL_DEF( FT_Error )
+  static FT_Error
   afm_parser_read_int( AFM_Parser  parser,
                        FT_Int*     aint )
   {
@@ -590,11 +590,17 @@
     char*          key;
     FT_Offset      len;
     int            n = -1;
+    FT_Int         tmp;
 
 
-    if ( afm_parser_read_int( parser, &fi->NumTrackKern ) )
+    if ( afm_parser_read_int( parser, &tmp ) )
         goto Fail;
 
+    if ( tmp < 0 )
+      goto Fail;
+
+    fi->NumTrackKern = (FT_UInt)tmp;
+
     if ( fi->NumTrackKern )
     {
       FT_Memory  memory = parser->memory;
@@ -615,7 +621,7 @@
       case AFM_TOKEN_TRACKKERN:
         n++;
 
-        if ( n >= fi->NumTrackKern )
+        if ( n >= (int)fi->NumTrackKern )
           goto Fail;
 
         tk = fi->TrackKerns + n;
@@ -639,7 +645,7 @@
       case AFM_TOKEN_ENDTRACKKERN:
       case AFM_TOKEN_ENDKERNDATA:
       case AFM_TOKEN_ENDFONTMETRICS:
-        fi->NumTrackKern = n + 1;
+        fi->NumTrackKern = (FT_UInt)( n + 1 );
         return FT_Err_Ok;
 
       case AFM_TOKEN_UNKNOWN:
@@ -688,11 +694,17 @@
     char*         key;
     FT_Offset     len;
     int           n = -1;
+    FT_Int        tmp;
 
 
-    if ( afm_parser_read_int( parser, &fi->NumKernPair ) )
+    if ( afm_parser_read_int( parser, &tmp ) )
       goto Fail;
 
+    if ( tmp < 0 )
+      goto Fail;
+
+    fi->NumKernPair = (FT_UInt)tmp;
+
     if ( fi->NumKernPair )
     {
       FT_Memory  memory = parser->memory;
@@ -720,7 +732,7 @@
 
           n++;
 
-          if ( n >= fi->NumKernPair )
+          if ( n >= (int)fi->NumKernPair )
             goto Fail;
 
           kp = fi->KernPairs + n;
@@ -733,8 +745,9 @@
           if ( r < 3 )
             goto Fail;
 
-          kp->index1 = shared_vals[0].u.i;
-          kp->index2 = shared_vals[1].u.i;
+          /* index values can't be negative */
+          kp->index1 = shared_vals[0].u.u;
+          kp->index2 = shared_vals[1].u.u;
           if ( token == AFM_TOKEN_KPY )
           {
             kp->x = 0;
@@ -752,7 +765,7 @@
       case AFM_TOKEN_ENDKERNPAIRS:
       case AFM_TOKEN_ENDKERNDATA:
       case AFM_TOKEN_ENDFONTMETRICS:
-        fi->NumKernPair = n + 1;
+        fi->NumKernPair = (FT_UInt)( n + 1 );
         ft_qsort( fi->KernPairs, fi->NumKernPair,
                   sizeof ( AFM_KernPairRec ),
                   afm_compare_kern_pairs );
@@ -815,7 +828,7 @@
 
   static FT_Error
   afm_parser_skip_section( AFM_Parser  parser,
-                           FT_UInt     n,
+                           FT_Int      n,
                            AFM_Token   end_section )
   {
     char*      key;
diff --git a/src/psaux/afmparse.h b/src/psaux/afmparse.h
index 35d9604..f922c4e 100644
--- a/src/psaux/afmparse.h
+++ b/src/psaux/afmparse.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    AFM parser (specification).                                          */
 /*                                                                         */
-/*  Copyright 2006 by                                                      */
+/*  Copyright 2006-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -61,6 +61,7 @@
       char*     s;
       FT_Fixed  f;
       FT_Int    i;
+      FT_UInt   u;
       FT_Bool   b;
 
     } u;
@@ -72,7 +73,7 @@
   FT_LOCAL( FT_Int )
   afm_parser_read_vals( AFM_Parser  parser,
                         AFM_Value   vals,
-                        FT_UInt     n );
+                        FT_Int      n );
 
   /* read the next key from the next line or column */
   FT_LOCAL( char* )
diff --git a/src/psaux/psaux.c b/src/psaux/psaux.c
index a4b9c5c..7f1d9aa 100644
--- a/src/psaux/psaux.c
+++ b/src/psaux/psaux.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType auxiliary PostScript driver component (body only).          */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2006 by                                     */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psaux/psauxerr.h b/src/psaux/psauxerr.h
index d52375f..97712f0 100644
--- a/src/psaux/psauxerr.h
+++ b/src/psaux/psauxerr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PS auxiliary module error codes (specification only).                */
 /*                                                                         */
-/*  Copyright 2001, 2012 by                                                */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psaux/psauxmod.c b/src/psaux/psauxmod.c
index 4b1249d..06fcab0 100644
--- a/src/psaux/psauxmod.c
+++ b/src/psaux/psauxmod.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType auxiliary PostScript module implementation (body).          */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002, 2003, 2006 by                               */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psaux/psauxmod.h b/src/psaux/psauxmod.h
index 1217236..ae6a8f9 100644
--- a/src/psaux/psauxmod.h
+++ b/src/psaux/psauxmod.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType auxiliary PostScript module implementation (specification). */
 /*                                                                         */
-/*  Copyright 2000-2001 by                                                 */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psaux/psconv.c b/src/psaux/psconv.c
index d0d8861..aca7412 100644
--- a/src/psaux/psconv.c
+++ b/src/psaux/psconv.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Some convenience conversions (body).                                 */
 /*                                                                         */
-/*  Copyright 2006, 2008, 2009, 2012-2013 by                               */
+/*  Copyright 2006-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -124,7 +124,7 @@
       if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
         break;
 
-      c = ft_char_table[*p & 0x7f];
+      c = ft_char_table[*p & 0x7F];
 
       if ( c < 0 || c >= base )
         break;
@@ -245,12 +245,13 @@
         if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
           break;
 
-        c = ft_char_table[*p & 0x7f];
+        c = ft_char_table[*p & 0x7F];
 
         if ( c < 0 || c >= 10 )
           break;
 
-        if ( decimal < 0xCCCCCCCL )
+        /* only add digit if we don't overflow */
+        if ( divider < 0xCCCCCCCL && decimal < 0xCCCCCCCL )
         {
           decimal = decimal * 10 + c;
 
@@ -488,8 +489,8 @@
       if ( c OP 0x80 )
         break;
 
-      c = ft_char_table[c & 0x7F];
-      if ( (unsigned)c >= 16 )
+      c = (FT_UInt)ft_char_table[c & 0x7F];
+      if ( c >= 16 )
         break;
 
       pad = ( pad << 4 ) | c;
@@ -520,7 +521,7 @@
       if ( *p OP 0x80 )
         break;
 
-      c = ft_char_table[*p & 0x7f];
+      c = ft_char_table[*p & 0x7F];
 
       if ( (unsigned)c >= 16 )
         break;
diff --git a/src/psaux/psconv.h b/src/psaux/psconv.h
index d91c762..10f1ff7 100644
--- a/src/psaux/psconv.h
+++ b/src/psaux/psconv.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Some convenience conversions (specification).                        */
 /*                                                                         */
-/*  Copyright 2006, 2012 by                                                */
+/*  Copyright 2006-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c
index b4b7d45..c7cbc67 100644
--- a/src/psaux/psobjs.c
+++ b/src/psaux/psobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auxiliary functions for PostScript fonts (body).                     */
 /*                                                                         */
-/*  Copyright 1996-2014 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -81,7 +81,7 @@
     table->max_elems = count;
     table->init      = 0xDEADBEEFUL;
     table->num_elems = 0;
-    table->block     = 0;
+    table->block     = NULL;
     table->capacity  = 0;
     table->cursor    = 0;
 
@@ -165,10 +165,10 @@
   /*    reallocation fails.                                                */
   /*                                                                       */
   FT_LOCAL_DEF( FT_Error )
-  ps_table_add( PS_Table    table,
-                FT_Int      idx,
-                void*       object,
-                FT_PtrDist  length )
+  ps_table_add( PS_Table  table,
+                FT_Int    idx,
+                void*     object,
+                FT_UInt   length )
   {
     if ( idx < 0 || idx >= table->max_elems )
     {
@@ -176,12 +176,6 @@
       return FT_THROW( Invalid_Argument );
     }
 
-    if ( length < 0 )
-    {
-      FT_ERROR(( "ps_table_add: invalid length\n" ));
-      return FT_THROW( Invalid_Argument );
-    }
-
     /* grow the base block if needed */
     if ( table->cursor + length > table->capacity )
     {
@@ -625,8 +619,8 @@
 
 
     token->type  = T1_TOKEN_TYPE_NONE;
-    token->start = 0;
-    token->limit = 0;
+    token->start = NULL;
+    token->limit = NULL;
 
     /* first of all, skip leading whitespace */
     ps_parser_skip_spaces( parser );
@@ -707,7 +701,7 @@
 
     if ( !token->limit )
     {
-      token->start = 0;
+      token->start = NULL;
       token->type  = T1_TOKEN_TYPE_NONE;
     }
 
@@ -932,7 +926,7 @@
                FT_Memory  memory )
   {
     FT_Byte*    cur = *cursor;
-    FT_PtrDist  len = 0;
+    FT_UInt     len = 0;
     FT_Int      count;
     FT_String*  result;
     FT_Error    error;
@@ -972,7 +966,7 @@
       }
     }
 
-    len = cur - *cursor;
+    len = (FT_UInt)( cur - *cursor );
     if ( cur >= limit || FT_ALLOC( result, len + 1 ) )
       return 0;
 
@@ -1230,7 +1224,7 @@
 
           for ( i = 0; i < 4; i++ )
           {
-            result = ps_tofixedarray( &cur, limit, max_objects,
+            result = ps_tofixedarray( &cur, limit, (FT_Int)max_objects,
                                       temp + i * max_objects, 0 );
             if ( result < 0 || (FT_UInt)result < max_objects )
             {
@@ -1321,7 +1315,7 @@
       goto Exit;
     }
     if ( (FT_UInt)num_elements > field->array_max )
-      num_elements = field->array_max;
+      num_elements = (FT_Int)field->array_max;
 
     old_cursor = parser->cursor;
     old_limit  = parser->limit;
@@ -1338,7 +1332,15 @@
     {
       parser->cursor = token->start;
       parser->limit  = token->limit;
-      ps_parser_load_field( parser, &fieldrec, objects, max_objects, 0 );
+
+      error = ps_parser_load_field( parser,
+                                    &fieldrec,
+                                    objects,
+                                    max_objects,
+                                    0 );
+      if ( error )
+        break;
+
       fieldrec.offset += fieldrec.size;
     }
 
@@ -1371,7 +1373,7 @@
   ps_parser_to_bytes( PS_Parser  parser,
                       FT_Byte*   bytes,
                       FT_Offset  max_bytes,
-                      FT_Long*   pnum_bytes,
+                      FT_ULong*  pnum_bytes,
                       FT_Bool    delimiters )
   {
     FT_Error  error = FT_Err_Ok;
@@ -1545,7 +1547,7 @@
       FT_GlyphLoader_Rewind( loader );
 
       builder->hints_globals = size->internal;
-      builder->hints_funcs   = 0;
+      builder->hints_funcs   = NULL;
 
       if ( hinting )
         builder->hints_funcs = glyph->internal->glyph_hints;
diff --git a/src/psaux/psobjs.h b/src/psaux/psobjs.h
index e380c60..bf879c1 100644
--- a/src/psaux/psobjs.h
+++ b/src/psaux/psobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auxiliary functions for PostScript fonts (specification).            */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003 by                                     */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -52,10 +52,10 @@
                 FT_Memory  memory );
 
   FT_LOCAL( FT_Error )
-  ps_table_add( PS_Table    table,
-                FT_Int      idx,
-                void*       object,
-                FT_PtrDist  length );
+  ps_table_add( PS_Table  table,
+                FT_Int    idx,
+                void*     object,
+                FT_UInt   length );
 
   FT_LOCAL( void )
   ps_table_done( PS_Table  table );
@@ -112,7 +112,7 @@
   ps_parser_to_bytes( PS_Parser  parser,
                       FT_Byte*   bytes,
                       FT_Offset  max_bytes,
-                      FT_Long*   pnum_bytes,
+                      FT_ULong*  pnum_bytes,
                       FT_Bool    delimiters );
 
 
diff --git a/src/psaux/t1cmap.c b/src/psaux/t1cmap.c
index 9e5bd34..2e2d433 100644
--- a/src/psaux/t1cmap.c
+++ b/src/psaux/t1cmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 character map support (body).                                 */
 /*                                                                         */
-/*  Copyright 2002, 2003, 2006, 2007, 2012 by                              */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -39,7 +39,7 @@
     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
 
 
-    cmap->num_glyphs    = face->type1.num_glyphs;
+    cmap->num_glyphs    = (FT_UInt)face->type1.num_glyphs;
     cmap->glyph_names   = (const char* const*)face->type1.glyph_names;
     cmap->sid_to_string = psnames->adobe_std_strings;
     cmap->code_to_sid   = is_expert ? psnames->adobe_expert_encoding
@@ -120,8 +120,12 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  t1_cmap_standard_init( T1_CMapStd  cmap )
+  t1_cmap_standard_init( T1_CMapStd  cmap,
+                         FT_Pointer  pointer )
   {
+    FT_UNUSED( pointer );
+
+
     t1_cmap_std_init( cmap, 0 );
     return 0;
   }
@@ -142,8 +146,12 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  t1_cmap_expert_init( T1_CMapStd  cmap )
+  t1_cmap_expert_init( T1_CMapStd  cmap,
+                       FT_Pointer  pointer )
   {
+    FT_UNUSED( pointer );
+
+
     t1_cmap_std_init( cmap, 1 );
     return 0;
   }
@@ -172,14 +180,17 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  t1_cmap_custom_init( T1_CMapCustom  cmap )
+  t1_cmap_custom_init( T1_CMapCustom  cmap,
+                       FT_Pointer     pointer )
   {
     T1_Face      face     = (T1_Face)FT_CMAP_FACE( cmap );
     T1_Encoding  encoding = &face->type1.encoding;
 
+    FT_UNUSED( pointer );
 
-    cmap->first   = encoding->code_first;
-    cmap->count   = (FT_UInt)( encoding->code_last - cmap->first );
+
+    cmap->first   = (FT_UInt)encoding->code_first;
+    cmap->count   = (FT_UInt)encoding->code_last - cmap->first;
     cmap->indices = encoding->char_index;
 
     FT_ASSERT( cmap->indices != NULL );
@@ -272,16 +283,19 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  t1_cmap_unicode_init( PS_Unicodes  unicodes )
+  t1_cmap_unicode_init( PS_Unicodes  unicodes,
+                        FT_Pointer   pointer )
   {
     T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );
     FT_Memory           memory  = FT_FACE_MEMORY( face );
     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
 
+    FT_UNUSED( pointer );
+
 
     return psnames->unicodes_init( memory,
                                    unicodes,
-                                   face->type1.num_glyphs,
+                                   (FT_UInt)face->type1.num_glyphs,
                                    (PS_GetGlyphNameFunc)&psaux_get_glyph_name,
                                    (PS_FreeGlyphNameFunc)NULL,
                                    (FT_Pointer)face );
diff --git a/src/psaux/t1cmap.h b/src/psaux/t1cmap.h
index 7ae65d2..b8ba06c 100644
--- a/src/psaux/t1cmap.h
+++ b/src/psaux/t1cmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 character map support (specification).                        */
 /*                                                                         */
-/*  Copyright 2002, 2003, 2006 by                                          */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c
index 6ce370b..2e19928 100644
--- a/src/psaux/t1decode.c
+++ b/src/psaux/t1decode.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript Type 1 decoding routines (body).                          */
 /*                                                                         */
-/*  Copyright 2000-2013 by                                                 */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -150,7 +150,7 @@
       if ( name                               &&
            name[0] == glyph_name[0]           &&
            ft_strcmp( name, glyph_name ) == 0 )
-        return n;
+        return (FT_Int)n;
     }
 
     return -1;
@@ -298,7 +298,7 @@
 
     /* the seac operator must not be nested */
     decoder->seac = TRUE;
-    error = t1_decoder_parse_glyph( decoder, bchar_index );
+    error = t1_decoder_parse_glyph( decoder, (FT_UInt)bchar_index );
     decoder->seac = FALSE;
     if ( error )
       goto Exit;
@@ -320,7 +320,7 @@
 
     /* the seac operator must not be nested */
     decoder->seac = TRUE;
-    error = t1_decoder_parse_glyph( decoder, achar_index );
+    error = t1_decoder_parse_glyph( decoder, (FT_UInt)achar_index );
     decoder->seac = FALSE;
     if ( error )
       goto Exit;
@@ -381,10 +381,10 @@
 
 
     /* compute random seed from stack address of parameter */
-    seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed              ^
-                         (FT_PtrDist)(char*)&decoder           ^
-                         (FT_PtrDist)(char*)&charstring_base ) &
-                         FT_ULONG_MAX ) ;
+    seed = (FT_Fixed)( ( (FT_Offset)(char*)&seed            ^
+                         (FT_Offset)(char*)&decoder         ^
+                         (FT_Offset)(char*)&charstring_base ) &
+                         FT_ULONG_MAX                         );
     seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
     if ( seed == 0 )
       seed = 0x7384;
@@ -796,7 +796,8 @@
           known_othersubr_result_cnt = 1;
 
           if ( hinter )
-            hinter->reset( hinter->hints, builder->current->n_points );
+            hinter->reset( hinter->hints,
+                           (FT_UInt)builder->current->n_points );
           break;
 
         case 12:
@@ -861,7 +862,7 @@
               *values++ = tmp;
             }
 
-            known_othersubr_result_cnt = num_points;
+            known_othersubr_result_cnt = (FT_Int)num_points;
             break;
           }
 
@@ -879,8 +880,8 @@
 
             idx = Fix2Int( top[0] );
 
-            if ( idx < 0                                           ||
-                 idx + blend->num_designs > decoder->len_buildchar )
+            if ( idx < 0                                                    ||
+                 (FT_UInt)idx + blend->num_designs > decoder->len_buildchar )
               goto Unexpected_OtherSubr;
 
             ft_memcpy( &decoder->buildchar[idx],
@@ -1094,14 +1095,17 @@
           /* close hints recording session */
           if ( hinter )
           {
-            if ( hinter->close( hinter->hints, builder->current->n_points ) )
+            if ( hinter->close( hinter->hints,
+                                (FT_UInt)builder->current->n_points ) )
               goto Syntax_Error;
 
             /* apply hints to the loaded glyph outline now */
-            hinter->apply( hinter->hints,
-                           builder->current,
-                           (PSH_Globals)builder->hints_globals,
-                           decoder->hint_mode );
+            error = hinter->apply( hinter->hints,
+                                   builder->current,
+                                   (PSH_Globals)builder->hints_globals,
+                                   decoder->hint_mode );
+            if ( error )
+              goto Fail;
           }
 
           /* add current outline to the glyph slot */
@@ -1344,7 +1348,7 @@
             FT_TRACE4(( " callsubr" ));
 
             idx = Fix2Int( top[0] );
-            if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs )
+            if ( idx < 0 || idx >= decoder->num_subrs )
             {
               FT_ERROR(( "t1_decoder_parse_charstrings:"
                          " invalid subrs index\n" ));
@@ -1577,7 +1581,7 @@
 
     /* retrieve PSNames interface from list of current modules */
     {
-      FT_Service_PsCMaps  psnames = 0;
+      FT_Service_PsCMaps  psnames;
 
 
       FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
diff --git a/src/psaux/t1decode.h b/src/psaux/t1decode.h
index 00728db..e83078f 100644
--- a/src/psaux/t1decode.h
+++ b/src/psaux/t1decode.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript Type 1 decoding routines (specification).                 */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002, 2003 by                                     */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c
index 644c76d..bfdb3ed 100644
--- a/src/pshinter/pshalgo.c
+++ b/src/pshinter/pshalgo.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript hinting algorithm (body).                                 */
 /*                                                                         */
-/*  Copyright 2001-2010, 2012-2014 by                                      */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used        */
@@ -30,16 +30,14 @@
 
 
 #ifdef DEBUG_HINTER
-  PSH_Hint_Table  ps_debug_hint_table = 0;
-  PSH_HintFunc    ps_debug_hint_func  = 0;
-  PSH_Glyph       ps_debug_glyph      = 0;
+  PSH_Hint_Table  ps_debug_hint_table = NULL;
+  PSH_HintFunc    ps_debug_hint_func  = NULL;
+  PSH_Glyph       ps_debug_glyph      = NULL;
 #endif
 
 
 #define  COMPUTE_INFLEXS  /* compute inflection points to optimize `S' */
                           /* and similar glyphs                        */
-#define  STRONGER         /* slightly increase the contrast of smooth  */
-                          /* hinting                                   */
 
 
   /*************************************************************************/
@@ -67,13 +65,13 @@
   {
     FT_FREE( table->zones );
     table->num_zones = 0;
-    table->zone      = 0;
+    table->zone      = NULL;
 
     FT_FREE( table->sort );
     FT_FREE( table->hints );
     table->num_hints   = 0;
     table->max_hints   = 0;
-    table->sort_global = 0;
+    table->sort_global = NULL;
   }
 
 
@@ -121,7 +119,7 @@
       PSH_Hint   hint2;
 
 
-      hint->parent = 0;
+      hint->parent = NULL;
       for ( ; count > 0; count--, sorted++ )
       {
         hint2 = sorted[0];
@@ -194,7 +192,7 @@
     table->sort_global = table->sort + count;
     table->num_hints   = 0;
     table->num_zones   = 0;
-    table->zone        = 0;
+    table->zone        = NULL;
 
     /* initialize the `table->hints' array */
     {
@@ -890,9 +888,6 @@
   /*************************************************************************/
   /*************************************************************************/
 
-#define PSH_ZONE_MIN  -3200000L
-#define PSH_ZONE_MAX  +3200000L
-
 #define xxDEBUG_ZONES
 
 
@@ -910,10 +905,6 @@
              zone->max );
   }
 
-#else
-
-#define psh_print_zone( x )  do { } while ( 0 )
-
 #endif /* DEBUG_ZONES */
 
 
@@ -1149,7 +1140,7 @@
     glyph->num_points   = 0;
     glyph->num_contours = 0;
 
-    glyph->memory = 0;
+    glyph->memory = NULL;
   }
 
 
@@ -1274,8 +1265,8 @@
          FT_NEW_ARRAY( glyph->contours, outline->n_contours ) )
       goto Exit;
 
-    glyph->num_points   = outline->n_points;
-    glyph->num_contours = outline->n_contours;
+    glyph->num_points   = (FT_UInt)outline->n_points;
+    glyph->num_contours = (FT_UInt)outline->n_contours;
 
     {
       FT_UInt      first = 0, next, n;
@@ -1285,15 +1276,15 @@
 
       for ( n = 0; n < glyph->num_contours; n++ )
       {
-        FT_Int     count;
+        FT_UInt    count;
         PSH_Point  point;
 
 
-        next  = outline->contours[n] + 1;
+        next  = (FT_UInt)outline->contours[n] + 1;
         count = next - first;
 
         contour->start = points + first;
-        contour->count = (FT_UInt)count;
+        contour->count = count;
 
         if ( count > 0 )
         {
@@ -1696,16 +1687,12 @@
       mask++;
       for ( ; num_masks > 1; num_masks--, mask++ )
       {
-        FT_UInt  next;
-        FT_Int   count;
+        FT_UInt  next = FT_MIN( mask->end_point, glyph->num_points );
 
 
-        next  = mask->end_point > glyph->num_points
-                  ? glyph->num_points
-                  : mask->end_point;
-        count = next - first;
-        if ( count > 0 )
+        if ( next > first )
         {
+          FT_UInt    count = next - first;
           PSH_Point  point = glyph->points + first;
 
 
@@ -2048,7 +2035,7 @@
       /* count the number of strong points in this contour */
       next      = start + contour->count;
       fit_count = 0;
-      first     = 0;
+      first     = NULL;
 
       for ( point = start; point < next; point++ )
         if ( psh_point_is_fitted( point ) )
diff --git a/src/pshinter/pshalgo.h b/src/pshinter/pshalgo.h
index c70f31e..8373e5e 100644
--- a/src/pshinter/pshalgo.h
+++ b/src/pshinter/pshalgo.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript hinting algorithm (specification).                        */
 /*                                                                         */
-/*  Copyright 2001-2003, 2008, 2013 by                                     */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -30,15 +30,12 @@
   /* handle to Hint structure */
   typedef struct PSH_HintRec_*  PSH_Hint;
 
-  /* hint bit-flags */
-  typedef enum  PSH_Hint_Flags_
-  {
-    PSH_HINT_GHOST  = PS_HINT_FLAG_GHOST,
-    PSH_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM,
-    PSH_HINT_ACTIVE = 4,
-    PSH_HINT_FITTED = 8
 
-  } PSH_Hint_Flags;
+  /* hint bit-flags */
+#define PSH_HINT_GHOST   PS_HINT_FLAG_GHOST
+#define PSH_HINT_BOTTOM  PS_HINT_FLAG_BOTTOM
+#define PSH_HINT_ACTIVE  4U
+#define PSH_HINT_FITTED  8U
 
 
 #define psh_hint_is_active( x )  ( ( (x)->flags & PSH_HINT_ACTIVE ) != 0 )
@@ -49,6 +46,7 @@
 #define psh_hint_deactivate( x )  (x)->flags &= ~PSH_HINT_ACTIVE
 #define psh_hint_set_fitted( x )  (x)->flags |=  PSH_HINT_FITTED
 
+
   /* hint structure */
   typedef struct  PSH_HintRec_
   {
@@ -112,14 +110,12 @@
 #define PSH_DIR_IS_VERTICAL( d )    PSH_DIR_COMPARE( d, PSH_DIR_VERTICAL )
 
 
- /* the following bit-flags are computed once by the glyph */
- /* analyzer, for both dimensions                          */
-  enum
-  {
-    PSH_POINT_OFF    = 1,   /* point is off the curve */
-    PSH_POINT_SMOOTH = 2,   /* point is smooth        */
-    PSH_POINT_INFLEX = 4    /* point is inflection    */
-  };
+  /* the following bit-flags are computed once by the glyph */
+  /* analyzer, for both dimensions                          */
+#define PSH_POINT_OFF     1U      /* point is off the curve */
+#define PSH_POINT_SMOOTH  2U      /* point is smooth        */
+#define PSH_POINT_INFLEX  4U      /* point is inflection    */
+
 
 #define psh_point_is_smooth( p )  ( (p)->flags & PSH_POINT_SMOOTH )
 #define psh_point_is_off( p )     ( (p)->flags & PSH_POINT_OFF    )
@@ -129,17 +125,16 @@
 #define psh_point_set_off( p )     (p)->flags |= PSH_POINT_OFF
 #define psh_point_set_inflex( p )  (p)->flags |= PSH_POINT_INFLEX
 
+
   /* the following bit-flags are re-computed for each dimension */
-  enum
-  {
-    PSH_POINT_STRONG   = 16,   /* point is strong                           */
-    PSH_POINT_FITTED   = 32,   /* point is already fitted                   */
-    PSH_POINT_EXTREMUM = 64,   /* point is local extremum                   */
-    PSH_POINT_POSITIVE = 128,  /* extremum has positive contour flow        */
-    PSH_POINT_NEGATIVE = 256,  /* extremum has negative contour flow        */
-    PSH_POINT_EDGE_MIN = 512,  /* point is aligned to left/bottom stem edge */
-    PSH_POINT_EDGE_MAX = 1024  /* point is aligned to top/right stem edge   */
-  };
+#define PSH_POINT_STRONG      16U /* point is strong                           */
+#define PSH_POINT_FITTED      32U /* point is already fitted                   */
+#define PSH_POINT_EXTREMUM    64U /* point is local extremum                   */
+#define PSH_POINT_POSITIVE   128U /* extremum has positive contour flow        */
+#define PSH_POINT_NEGATIVE   256U /* extremum has negative contour flow        */
+#define PSH_POINT_EDGE_MIN   512U /* point is aligned to left/bottom stem edge */
+#define PSH_POINT_EDGE_MAX  1024U /* point is aligned to top/right stem edge   */
+
 
 #define psh_point_is_strong( p )    ( (p)->flags2 & PSH_POINT_STRONG )
 #define psh_point_is_fitted( p )    ( (p)->flags2 & PSH_POINT_FITTED )
diff --git a/src/pshinter/pshglob.c b/src/pshinter/pshglob.c
index f75bae4..6723b71 100644
--- a/src/pshinter/pshglob.c
+++ b/src/pshinter/pshglob.c
@@ -5,7 +5,7 @@
 /*    PostScript hinter global hinting management (body).                  */
 /*    Inspired by the new auto-hinter module.                              */
 /*                                                                         */
-/*  Copyright 2001-2004, 2006, 2010, 2012, 2013 by                         */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used        */
@@ -23,7 +23,7 @@
 #include "pshglob.h"
 
 #ifdef DEBUG_HINTER
-  PSH_Globals  ps_debug_globals = 0;
+  PSH_Globals  ps_debug_globals = NULL;
 #endif
 
 
@@ -240,7 +240,7 @@
                        FT_Int     family )
   {
     PSH_Blue_Table  top_table, bot_table;
-    FT_Int          count_top, count_bot;
+    FT_UInt         count_top, count_bot;
 
 
     if ( family )
@@ -369,7 +369,7 @@
   {
     FT_UInt         count;
     FT_UInt         num;
-    PSH_Blue_Table  table = 0;
+    PSH_Blue_Table  table = NULL;
 
     /*                                                        */
     /* Determine whether we need to suppress overshoots or    */
@@ -635,7 +635,7 @@
       FT_FREE( globals );
 
 #ifdef DEBUG_HINTER
-      ps_debug_globals = 0;
+      ps_debug_globals = NULL;
 #endif
     }
   }
@@ -750,7 +750,7 @@
   }
 
 
-  FT_LOCAL_DEF( FT_Error )
+  FT_LOCAL_DEF( void )
   psh_globals_set_scale( PSH_Globals  globals,
                          FT_Fixed     x_scale,
                          FT_Fixed     y_scale,
@@ -780,8 +780,6 @@
       psh_globals_scale_widths( globals, 1 );
       psh_blues_scale_zones( &globals->blues, y_scale, y_delta );
     }
-
-    return 0;
   }
 
 
diff --git a/src/pshinter/pshglob.h b/src/pshinter/pshglob.h
index c511626..c376df7 100644
--- a/src/pshinter/pshglob.h
+++ b/src/pshinter/pshglob.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript hinter global hinting management.                         */
 /*                                                                         */
-/*  Copyright 2001, 2002, 2003 by                                          */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -167,7 +167,7 @@
                             FT_Int         org_width );
 #endif
 
-  FT_LOCAL( FT_Error )
+  FT_LOCAL( void )
   psh_globals_set_scale( PSH_Globals  globals,
                          FT_Fixed     x_scale,
                          FT_Fixed     y_scale,
diff --git a/src/pshinter/pshinter.c b/src/pshinter/pshinter.c
index b35a2a9..9e65fe2 100644
--- a/src/pshinter/pshinter.c
+++ b/src/pshinter/pshinter.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType PostScript Hinting module                                   */
 /*                                                                         */
-/*  Copyright 2001, 2003 by                                                */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/pshinter/pshmod.c b/src/pshinter/pshmod.c
index cdeaca1..961b468 100644
--- a/src/pshinter/pshmod.c
+++ b/src/pshinter/pshmod.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType PostScript hinter module implementation (body).             */
 /*                                                                         */
-/*  Copyright 2001, 2002, 2007, 2009, 2012 by                              */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/pshinter/pshmod.h b/src/pshinter/pshmod.h
index 0ae7e96..a58d856 100644
--- a/src/pshinter/pshmod.h
+++ b/src/pshinter/pshmod.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript hinter module interface (specification).                  */
 /*                                                                         */
-/*  Copyright 2001 by                                                      */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/pshinter/pshnterr.h b/src/pshinter/pshnterr.h
index 7cc180f..ce790a8 100644
--- a/src/pshinter/pshnterr.h
+++ b/src/pshinter/pshnterr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PS Hinter error codes (specification only).                          */
 /*                                                                         */
-/*  Copyright 2003, 2012 by                                                */
+/*  Copyright 2003-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/pshinter/pshpic.c b/src/pshinter/pshpic.c
index 568f4ac..afd8fb9 100644
--- a/src/pshinter/pshpic.c
+++ b/src/pshinter/pshpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for pshinter module. */
 /*                                                                         */
-/*  Copyright 2009, 2010, 2012, 2013 by                                    */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/pshinter/pshpic.h b/src/pshinter/pshpic.h
index b46f853..62de457 100644
--- a/src/pshinter/pshpic.h
+++ b/src/pshinter/pshpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for pshinter module. */
 /*                                                                         */
-/*  Copyright 2009, 2012, 2013 by                                          */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/pshinter/pshrec.c b/src/pshinter/pshrec.c
index cd66ea8..f8895fc 100644
--- a/src/pshinter/pshrec.c
+++ b/src/pshinter/pshrec.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType PostScript hints recorder (body).                           */
 /*                                                                         */
-/*  Copyright 2001-2004, 2007, 2009, 2013 by                               */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -31,7 +31,7 @@
 #define FT_COMPONENT  trace_pshrec
 
 #ifdef DEBUG_HINTER
-  PS_Hints  ps_debug_hints         = 0;
+  PS_Hints  ps_debug_hints         = NULL;
   int       ps_debug_no_horz_hints = 0;
   int       ps_debug_no_vert_hints = 0;
 #endif
@@ -85,7 +85,7 @@
   {
     FT_Error  error = FT_Err_Ok;
     FT_UInt   count;
-    PS_Hint   hint = 0;
+    PS_Hint   hint = NULL;
 
 
     count = table->num_hints;
@@ -167,12 +167,12 @@
   /* clear a given bit */
   static void
   ps_mask_clear_bit( PS_Mask  mask,
-                     FT_Int   idx )
+                     FT_UInt  idx )
   {
     FT_Byte*  p;
 
 
-    if ( (FT_UInt)idx >= mask->num_bits )
+    if ( idx >= mask->num_bits )
       return;
 
     p    = mask->bytes + ( idx >> 3 );
@@ -183,17 +183,14 @@
   /* set a given bit, possibly grow the mask */
   static FT_Error
   ps_mask_set_bit( PS_Mask    mask,
-                   FT_Int     idx,
+                   FT_UInt    idx,
                    FT_Memory  memory )
   {
     FT_Error  error = FT_Err_Ok;
     FT_Byte*  p;
 
 
-    if ( idx < 0 )
-      goto Exit;
-
-    if ( (FT_UInt)idx >= mask->num_bits )
+    if ( idx >= mask->num_bits )
     {
       error = ps_mask_ensure( mask, idx + 1, memory );
       if ( error )
@@ -257,7 +254,7 @@
   {
     FT_UInt   count;
     FT_Error  error = FT_Err_Ok;
-    PS_Mask   mask  = 0;
+    PS_Mask   mask  = NULL;
 
 
     count = table->num_masks;
@@ -372,8 +369,8 @@
   /* test whether two masks in a table intersect */
   static FT_Int
   ps_mask_table_test_intersect( PS_Mask_Table  table,
-                                FT_Int         index1,
-                                FT_Int         index2 )
+                                FT_UInt        index1,
+                                FT_UInt        index2 )
   {
     PS_Mask   mask1  = table->masks + index1;
     PS_Mask   mask2  = table->masks + index2;
@@ -404,23 +401,25 @@
   /* merge two masks, used by ps_mask_table_merge_all */
   static FT_Error
   ps_mask_table_merge( PS_Mask_Table  table,
-                       FT_Int         index1,
-                       FT_Int         index2,
+                       FT_UInt        index1,
+                       FT_UInt        index2,
                        FT_Memory      memory )
   {
-    FT_UInt   temp;
     FT_Error  error = FT_Err_Ok;
 
 
     /* swap index1 and index2 so that index1 < index2 */
     if ( index1 > index2 )
     {
+      FT_UInt  temp;
+
+
       temp   = index1;
       index1 = index2;
       index2 = temp;
     }
 
-    if ( index1 < index2 && index1 >= 0 && index2 < (FT_Int)table->num_masks )
+    if ( index1 < index2 && index2 < table->num_masks )
     {
       /* we need to merge the bitsets of index1 and index2 with a */
       /* simple union                                             */
@@ -453,7 +452,7 @@
         /* merge (unite) the bitsets */
         read  = mask2->bytes;
         write = mask1->bytes;
-        pos   = (FT_UInt)( ( count2 + 7 ) >> 3 );
+        pos   = ( count2 + 7 ) >> 3;
 
         for ( ; pos > 0; pos-- )
         {
@@ -468,14 +467,17 @@
       mask2->num_bits  = 0;
       mask2->end_point = 0;
 
-      delta = table->num_masks - 1 - index2; /* number of masks to move */
+      /* number of masks to move */
+      delta = (FT_Int)( table->num_masks - 1 - index2 );
       if ( delta > 0 )
       {
         /* move to end of table for reuse */
         PS_MaskRec  dummy = *mask2;
 
 
-        ft_memmove( mask2, mask2 + 1, delta * sizeof ( PS_MaskRec ) );
+        ft_memmove( mask2,
+                    mask2 + 1,
+                    (FT_UInt)delta * sizeof ( PS_MaskRec ) );
 
         mask2[delta] = dummy;
       }
@@ -502,13 +504,19 @@
     FT_Error  error = FT_Err_Ok;
 
 
-    for ( index1 = table->num_masks - 1; index1 > 0; index1-- )
+    /* both loops go down to 0, thus FT_Int for index1 and index2 */
+    for ( index1 = (FT_Int)table->num_masks - 1; index1 > 0; index1-- )
     {
       for ( index2 = index1 - 1; index2 >= 0; index2-- )
       {
-        if ( ps_mask_table_test_intersect( table, index1, index2 ) )
+        if ( ps_mask_table_test_intersect( table,
+                                           (FT_UInt)index1,
+                                           (FT_UInt)index2 ) )
         {
-          error = ps_mask_table_merge( table, index2, index1, memory );
+          error = ps_mask_table_merge( table,
+                                       (FT_UInt)index2,
+                                       (FT_UInt)index1,
+                                       memory );
           if ( error )
             goto Exit;
 
@@ -670,8 +678,8 @@
     {
       PS_Mask  mask;
       FT_UInt  idx;
-      FT_UInt  max   = dim->hints.num_hints;
-      PS_Hint  hint  = dim->hints.hints;
+      FT_UInt  max  = dim->hints.num_hints;
+      PS_Hint  hint = dim->hints.hints;
 
 
       for ( idx = 0; idx < max; idx++, hint++ )
@@ -742,17 +750,26 @@
     }
 
     /* now, set the bits for our hints in the counter mask */
-    error = ps_mask_set_bit( counter, hint1, memory );
-    if ( error )
-      goto Exit;
+    if ( hint1 >= 0 )
+    {
+      error = ps_mask_set_bit( counter, (FT_UInt)hint1, memory );
+      if ( error )
+        goto Exit;
+    }
 
-    error = ps_mask_set_bit( counter, hint2, memory );
-    if ( error )
-      goto Exit;
+    if ( hint2 >= 0 )
+    {
+      error = ps_mask_set_bit( counter, (FT_UInt)hint2, memory );
+      if ( error )
+        goto Exit;
+    }
 
-    error = ps_mask_set_bit( counter, hint3, memory );
-    if ( error )
-      goto Exit;
+    if ( hint3 >= 0 )
+    {
+      error = ps_mask_set_bit( counter, (FT_UInt)hint3, memory );
+      if ( error )
+        goto Exit;
+    }
 
   Exit:
     return error;
@@ -793,17 +810,16 @@
     ps_dimension_done( &hints->dimension[1], memory );
 
     hints->error  = FT_Err_Ok;
-    hints->memory = 0;
+    hints->memory = NULL;
   }
 
 
-  FT_LOCAL( FT_Error )
+  FT_LOCAL( void )
   ps_hints_init( PS_Hints   hints,
                  FT_Memory  memory )
   {
     FT_MEM_ZERO( hints, sizeof ( *hints ) );
     hints->memory = memory;
-    return FT_Err_Ok;
   }
 
 
@@ -812,78 +828,57 @@
   ps_hints_open( PS_Hints      hints,
                  PS_Hint_Type  hint_type )
   {
-    switch ( hint_type )
-    {
-    case PS_HINT_TYPE_1:
-    case PS_HINT_TYPE_2:
-      hints->error     = FT_Err_Ok;
-      hints->hint_type = hint_type;
+    hints->error     = FT_Err_Ok;
+    hints->hint_type = hint_type;
 
-      ps_dimension_init( &hints->dimension[0] );
-      ps_dimension_init( &hints->dimension[1] );
-      break;
-
-    default:
-      hints->error     = FT_THROW( Invalid_Argument );
-      hints->hint_type = hint_type;
-
-      FT_TRACE0(( "ps_hints_open: invalid charstring type\n" ));
-      break;
-    }
+    ps_dimension_init( &hints->dimension[0] );
+    ps_dimension_init( &hints->dimension[1] );
   }
 
 
   /* add one or more stems to the current hints table */
   static void
   ps_hints_stem( PS_Hints  hints,
-                 FT_Int    dimension,
-                 FT_UInt   count,
+                 FT_UInt   dimension,
+                 FT_Int    count,
                  FT_Long*  stems )
   {
-    if ( !hints->error )
+    PS_Dimension  dim;
+
+
+    if ( hints->error )
+      return;
+
+    /* limit "dimension" to 0..1 */
+    if ( dimension > 1 )
     {
-      /* limit "dimension" to 0..1 */
-      if ( dimension < 0 || dimension > 1 )
+      FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n",
+                  dimension ));
+      dimension = ( dimension != 0 );
+    }
+
+    /* record the stems in the current hints/masks table */
+    /* (Type 1 & 2's `hstem' or `vstem' operators)       */
+    dim = &hints->dimension[dimension];
+
+    for ( ; count > 0; count--, stems += 2 )
+    {
+      FT_Error   error;
+      FT_Memory  memory = hints->memory;
+
+
+      error = ps_dimension_add_t1stem( dim,
+                                       (FT_Int)stems[0],
+                                       (FT_Int)stems[1],
+                                       memory,
+                                       NULL );
+      if ( error )
       {
-        FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n",
-                    dimension ));
-        dimension = ( dimension != 0 );
-      }
+        FT_ERROR(( "ps_hints_stem: could not add stem"
+                   " (%d,%d) to hints table\n", stems[0], stems[1] ));
 
-      /* record the stems in the current hints/masks table */
-      switch ( hints->hint_type )
-      {
-      case PS_HINT_TYPE_1:  /* Type 1 "hstem" or "vstem" operator */
-      case PS_HINT_TYPE_2:  /* Type 2 "hstem" or "vstem" operator */
-        {
-          PS_Dimension  dim = &hints->dimension[dimension];
-
-
-          for ( ; count > 0; count--, stems += 2 )
-          {
-            FT_Error   error;
-            FT_Memory  memory = hints->memory;
-
-
-            error = ps_dimension_add_t1stem(
-                      dim, (FT_Int)stems[0], (FT_Int)stems[1],
-                      memory, NULL );
-            if ( error )
-            {
-              FT_ERROR(( "ps_hints_stem: could not add stem"
-                         " (%d,%d) to hints table\n", stems[0], stems[1] ));
-
-              hints->error = error;
-              return;
-            }
-          }
-          break;
-        }
-
-      default:
-        FT_TRACE0(( "ps_hints_stem: called with invalid hint type (%d)\n",
-                    hints->hint_type ));
-        break;
+        hints->error = error;
+        return;
       }
     }
   }
@@ -892,7 +887,7 @@
   /* add one Type1 counter stem to the current hints table */
   static void
   ps_hints_t1stem3( PS_Hints   hints,
-                    FT_Int     dimension,
+                    FT_UInt    dimension,
                     FT_Fixed*  stems )
   {
     FT_Error  error = FT_Err_Ok;
@@ -907,7 +902,7 @@
 
 
       /* limit "dimension" to 0..1 */
-      if ( dimension < 0 || dimension > 1 )
+      if ( dimension > 1 )
       {
         FT_TRACE0(( "ps_hints_t1stem3: invalid dimension (%d) used\n",
                     dimension ));
@@ -1129,7 +1124,7 @@
 
   static void
   t1_hints_stem( T1_Hints   hints,
-                 FT_Int     dimension,
+                 FT_UInt    dimension,
                  FT_Fixed*  coords )
   {
     FT_Pos  stems[2];
@@ -1173,12 +1168,12 @@
 
   static void
   t2_hints_stems( T2_Hints   hints,
-                  FT_Int     dimension,
+                  FT_UInt    dimension,
                   FT_Int     count,
                   FT_Fixed*  coords )
   {
-    FT_Pos  stems[32], y, n;
-    FT_Int  total = count;
+    FT_Pos  stems[32], y;
+    FT_Int  total = count, n;
 
 
     y = 0;
diff --git a/src/pshinter/pshrec.h b/src/pshinter/pshrec.h
index dcb3197..2b1ad94 100644
--- a/src/pshinter/pshrec.h
+++ b/src/pshinter/pshrec.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Postscript (Type1/Type2) hints recorder (specification).             */
 /*                                                                         */
-/*  Copyright 2001, 2002, 2003, 2006, 2008 by                              */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -61,12 +61,8 @@
 
 
   /* hint flags */
-  typedef enum  PS_Hint_Flags_
-  {
-    PS_HINT_FLAG_GHOST  = 1,
-    PS_HINT_FLAG_BOTTOM = 2
-
-  } PS_Hint_Flags;
+#define PS_HINT_FLAG_GHOST   1U
+#define PS_HINT_FLAG_BOTTOM  2U
 
 
   /* hint descriptor */
@@ -141,7 +137,7 @@
   /* */
 
   /* initialize hints recorder */
-  FT_LOCAL( FT_Error )
+  FT_LOCAL( void )
   ps_hints_init( PS_Hints   hints,
                  FT_Memory  memory );
 
diff --git a/src/psnames/psmodule.c b/src/psnames/psmodule.c
index 0a5bcb7..0f04c2f 100644
--- a/src/psnames/psmodule.c
+++ b/src/psnames/psmodule.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PSNames module implementation (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2003, 2005-2008, 2012, 2013 by                          */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -312,7 +312,7 @@
 
     /* we first allocate the table */
     table->num_maps = 0;
-    table->maps     = 0;
+    table->maps     = NULL;
 
     if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) )
     {
@@ -563,7 +563,7 @@
   psnames_get_service( FT_Module    module,
                        const char*  service_id )
   {
-    /* PSCMAPS_SERVICES_GET derefers `library' in PIC mode */
+    /* PSCMAPS_SERVICES_GET dereferences `library' in PIC mode */
 #ifdef FT_CONFIG_OPTION_PIC
     FT_Library  library;
 
diff --git a/src/psnames/psmodule.h b/src/psnames/psmodule.h
index 28fa148..f85f322 100644
--- a/src/psnames/psmodule.h
+++ b/src/psnames/psmodule.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level PSNames module interface (specification).                 */
 /*                                                                         */
-/*  Copyright 1996-2001 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psnames/psnamerr.h b/src/psnames/psnamerr.h
index acda7f9..09cc247 100644
--- a/src/psnames/psnamerr.h
+++ b/src/psnames/psnamerr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PS names module error codes (specification only).                    */
 /*                                                                         */
-/*  Copyright 2001, 2012 by                                                */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psnames/psnames.c b/src/psnames/psnames.c
index 1ede225..a438596 100644
--- a/src/psnames/psnames.c
+++ b/src/psnames/psnames.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType PSNames module component (body only).                       */
 /*                                                                         */
-/*  Copyright 1996-2001 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psnames/pspic.c b/src/psnames/pspic.c
index 3820f65..1394f97 100644
--- a/src/psnames/pspic.c
+++ b/src/psnames/pspic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for psnames module.  */
 /*                                                                         */
-/*  Copyright 2009, 2010, 2012, 2013 by                                    */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psnames/pspic.h b/src/psnames/pspic.h
index 6ff002c..88ccda3 100644
--- a/src/psnames/pspic.h
+++ b/src/psnames/pspic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for psnames module.  */
 /*                                                                         */
-/*  Copyright 2009, 2012 by                                                */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psnames/pstables.h b/src/psnames/pstables.h
index 0a6637f..3f31c31 100644
--- a/src/psnames/pstables.h
+++ b/src/psnames/pstables.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript glyph names.                                              */
 /*                                                                         */
-/*  Copyright 2005, 2008, 2011 by                                          */
+/*  Copyright 2005-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/raster/ftmisc.h b/src/raster/ftmisc.h
index 703155a..19be4ca 100644
--- a/src/raster/ftmisc.h
+++ b/src/raster/ftmisc.h
@@ -5,7 +5,7 @@
 /*    Miscellaneous macros for stand-alone rasterizer (specification       */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 2005, 2009, 2010 by                                          */
+/*  Copyright 2005-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used        */
diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c
index abbecb7..eeab143 100644
--- a/src/raster/ftraster.c
+++ b/src/raster/ftraster.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph rasterizer (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2003, 2005, 2007-2014 by                                */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -49,6 +49,10 @@
 
 #ifdef _STANDALONE_
 
+  /* The size in bytes of the render pool used by the scan-line converter  */
+  /* to do all of its work.                                                */
+#define FT_RENDER_POOL_SIZE  16384L
+
 #define FT_CONFIG_STANDARD_LIBRARY_H  <stdlib.h>
 
 #include <string.h>           /* for memset */
@@ -150,14 +154,6 @@
   /* define DEBUG_RASTER if you want to compile a debugging version */
 /* #define DEBUG_RASTER */
 
-  /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */
-  /* 5-levels anti-aliasing                                       */
-/* #define FT_RASTER_OPTION_ANTI_ALIASING */
-
-  /* The size of the two-lines intermediate bitmap used */
-  /* for anti-aliasing, in bytes.                       */
-#define RASTER_GRAY_LINES  2048
-
 
   /*************************************************************************/
   /*************************************************************************/
@@ -183,6 +179,8 @@
 #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 */
@@ -199,6 +197,7 @@
 #define FT_TRACE( x )   do { } while ( 0 )    /* nothing */
 #define FT_TRACE1( x )  do { } while ( 0 )    /* nothing */
 #define FT_TRACE6( x )  do { } while ( 0 )    /* nothing */
+#define FT_TRACE7( x )  do { } while ( 0 )    /* nothing */
 #endif
 
 #ifndef FT_THROW
@@ -318,7 +317,7 @@
 
   typedef union  Alignment_
   {
-    long    l;
+    Long    l;
     void*   p;
     void  (*f)(void);
 
@@ -334,9 +333,9 @@
 
 
   /* values for the `flags' bit field */
-#define Flow_Up           0x8
-#define Overshoot_Top     0x10
-#define Overshoot_Bottom  0x20
+#define Flow_Up           0x08U
+#define Overshoot_Top     0x10U
+#define Overshoot_Bottom  0x20U
 
 
   /* States of each line, arc, and profile */
@@ -358,14 +357,14 @@
     FT_F26Dot6  X;           /* current coordinate during sweep          */
     PProfile    link;        /* link to next profile (various purposes)  */
     PLong       offset;      /* start of profile's data in render pool   */
-    unsigned    flags;       /* Bit 0-2: drop-out mode                   */
+    UShort      flags;       /* Bit 0-2: drop-out mode                   */
                              /* Bit 3: profile orientation (up/down)     */
                              /* Bit 4: is top profile?                   */
                              /* Bit 5: is bottom profile?                */
-    long        height;      /* profile's height in scanlines            */
-    long        start;       /* profile's starting scanline              */
+    Long        height;      /* profile's height in scanlines            */
+    Long        start;       /* profile's starting scanline              */
 
-    unsigned    countL;      /* number of lines to step before this      */
+    Int         countL;      /* number of lines to step before this      */
                              /* profile becomes drawable                 */
 
     PProfile    next;        /* next profile in same contour, used       */
@@ -387,7 +386,7 @@
 
 
 #define AlignProfileSize \
-  ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( long ) )
+  ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( Long ) )
 
 
 #undef RAS_ARG
@@ -451,7 +450,7 @@
 #define CEILING( x )  ( ( (x) + ras.precision - 1 ) & -ras.precision )
 #define TRUNC( x )    ( (Long)(x) >> ras.precision_bits )
 #define FRAC( x )     ( (x) & ( ras.precision - 1 ) )
-#define SCALED( x )   ( ( (ULong)(x) << ras.scale_shift ) - ras.precision_half )
+#define SCALED( x )   ( ( (Long)(x) << ras.scale_shift ) - ras.precision_half )
 
 #define IS_BOTTOM_OVERSHOOT( x ) \
           (Bool)( CEILING( x ) - x >= ras.precision_half )
@@ -514,9 +513,6 @@
 
     Short       traceIncr;          /* sweep's increment in target bitmap  */
 
-    Short       gray_min_x;         /* current min x during gray rendering */
-    Short       gray_max_x;         /* current max x during gray rendering */
-
     /* dispatch variables */
 
     Function_Sweep_Init*  Proc_Sweep_Init;
@@ -529,45 +525,19 @@
     Bool        second_pass;        /* indicates whether a horizontal pass */
                                     /* should be performed to control      */
                                     /* drop-out accurately when calling    */
-                                    /* Render_Glyph.  Note that there is   */
-                                    /* no horizontal pass during gray      */
-                                    /* rendering.                          */
+                                    /* Render_Glyph.                       */
 
     TPoint      arcs[3 * MaxBezier + 1]; /* The Bezier stack               */
 
     black_TBand  band_stack[16];    /* band stack used for sub-banding     */
     Int          band_top;          /* band stack top                      */
 
-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
-
-    Byte*       grays;
-
-    Byte        gray_lines[RASTER_GRAY_LINES];
-                                /* Intermediate table used to render the   */
-                                /* graylevels pixmaps.                     */
-                                /* gray_lines is a buffer holding two      */
-                                /* monochrome scanlines                    */
-
-    Short       gray_width;     /* width in bytes of one monochrome        */
-                                /* intermediate scanline of gray_lines.    */
-                                /* Each gray pixel takes 2 bits long there */
-
-                       /* The gray_lines must hold 2 lines, thus with size */
-                       /* in bytes of at least `gray_width*2'.             */
-
-#endif /* FT_RASTER_ANTI_ALIASING */
-
   };
 
 
   typedef struct  black_TRaster_
   {
-    char*          buffer;
-    long           buffer_size;
     void*          memory;
-    black_PWorker  worker;
-    Byte           grays[5];
-    Short          gray_width;
 
   } black_TRaster, *black_PRaster;
 
@@ -583,70 +553,6 @@
 #endif /* !FT_STATIC_RASTER */
 
 
-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
-
-  /* A lookup table used to quickly count set bits in four gray 2x2 */
-  /* cells.  The values of the table have been produced with the    */
-  /* following code:                                                */
-  /*                                                                */
-  /*   for ( i = 0; i < 256; i++ )                                  */
-  /*   {                                                            */
-  /*     l = 0;                                                     */
-  /*     j = i;                                                     */
-  /*                                                                */
-  /*     for ( c = 0; c < 4; c++ )                                  */
-  /*     {                                                          */
-  /*       l <<= 4;                                                 */
-  /*                                                                */
-  /*       if ( j & 0x80 ) l++;                                     */
-  /*       if ( j & 0x40 ) l++;                                     */
-  /*                                                                */
-  /*       j = ( j << 2 ) & 0xFF;                                   */
-  /*     }                                                          */
-  /*     printf( "0x%04X", l );                                     */
-  /*   }                                                            */
-  /*                                                                */
-
-  static const short  count_table[256] =
-  {
-    0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012,
-    0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022,
-    0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,
-    0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,
-    0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,
-    0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,
-    0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212,
-    0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222,
-    0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,
-    0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,
-    0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
-    0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
-    0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
-    0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
-    0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,
-    0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,
-    0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,
-    0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,
-    0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
-    0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
-    0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
-    0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
-    0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,
-    0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,
-    0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012,
-    0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022,
-    0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,
-    0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,
-    0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,
-    0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,
-    0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212,
-    0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222
-  };
-
-#endif /* FT_RASTER_OPTION_ANTI_ALIASING */
-
-
-
   /*************************************************************************/
   /*************************************************************************/
   /**                                                                     **/
@@ -677,11 +583,11 @@
      * approximating it as a straight segment.  The default value of 32 (for
      * low accuracy) corresponds to
      *
-     *   32 / 64 == 0.5 pixels ,
+     *   32 / 64 == 0.5 pixels,
      *
      * while for the high accuracy case we have
      *
-     *   256/ (1 << 12) = 0.0625 pixels .
+     *   256 / (1 << 12) = 0.0625 pixels.
      *
      * `precision_jitter' is an epsilon threshold used in
      * `Vertical_Sweep_Span' to deal with small imperfections in the Bezier
@@ -764,13 +670,13 @@
       if ( overshoot )
         ras.cProfile->flags |= Overshoot_Bottom;
 
-      FT_TRACE6(( "New ascending profile = %p\n", ras.cProfile ));
+      FT_TRACE6(( "  new ascending profile = %p\n", ras.cProfile ));
       break;
 
     case Descending_State:
       if ( overshoot )
         ras.cProfile->flags |= Overshoot_Top;
-      FT_TRACE6(( "New descending profile = %p\n", ras.cProfile ));
+      FT_TRACE6(( "  new descending profile = %p\n", ras.cProfile ));
       break;
 
     default:
@@ -825,7 +731,7 @@
       PProfile  oldProfile;
 
 
-      FT_TRACE6(( "Ending profile %p, start = %ld, height = %ld\n",
+      FT_TRACE6(( "  ending profile %p, start = %ld, height = %ld\n",
                   ras.cProfile, ras.cProfile->start, h ));
 
       ras.cProfile->height = h;
@@ -1813,7 +1719,7 @@
   static Bool
   Decompose_Curve( RAS_ARGS UShort  first,
                             UShort  last,
-                            int     flipped )
+                            Int     flipped )
   {
     FT_Vector   v_last;
     FT_Vector   v_control;
@@ -1824,7 +1730,7 @@
     FT_Vector*  limit;
     char*       tags;
 
-    unsigned    tag;       /* current point's state           */
+    UInt        tag;       /* current point's state           */
 
 
     points = ras.outline.points;
@@ -2035,10 +1941,10 @@
   /*    rendering.                                                         */
   /*                                                                       */
   static Bool
-  Convert_Glyph( RAS_ARGS int  flipped )
+  Convert_Glyph( RAS_ARGS Int  flipped )
   {
-    int       i;
-    unsigned  start;
+    Int   i;
+    UInt  start;
 
 
     ras.fProfile = NULL;
@@ -2064,12 +1970,12 @@
       ras.state    = Unknown_State;
       ras.gProfile = NULL;
 
-      if ( Decompose_Curve( RAS_VARS (unsigned short)start,
-                                     ras.outline.contours[i],
+      if ( Decompose_Curve( RAS_VARS (UShort)start,
+                                     (UShort)ras.outline.contours[i],
                                      flipped ) )
         return FAILURE;
 
-      start = ras.outline.contours[i] + 1;
+      start = (UShort)ras.outline.contours[i] + 1;
 
       /* we must now check whether the extreme arcs join or not */
       if ( FRAC( ras.lastY ) == 0 &&
@@ -2083,7 +1989,8 @@
         /* to be drawn.                                                   */
 
       lastProfile = ras.cProfile;
-      if ( ras.cProfile->flags & Flow_Up )
+      if ( ras.top != ras.cProfile->offset &&
+           ( ras.cProfile->flags & Flow_Up ) )
         o = IS_TOP_OVERSHOOT( ras.lastY );
       else
         o = IS_BOTTOM_OVERSHOOT( ras.lastY );
@@ -2267,10 +2174,7 @@
     ras.traceIncr = (Short)-pitch;
     ras.traceOfs  = -*min * pitch;
     if ( pitch > 0 )
-      ras.traceOfs += ( ras.target.rows - 1 ) * pitch;
-
-    ras.gray_min_x = 0;
-    ras.gray_max_x = 0;
+      ras.traceOfs += (Long)( ras.target.rows - 1 ) * pitch;
   }
 
 
@@ -2291,6 +2195,14 @@
     FT_UNUSED( right );
 
 
+    /* in high-precision mode, we need 12 digits after the comma to */
+    /* represent multiples of 1/(1<<12) = 1/4096                    */
+    FT_TRACE7(( "  y=%d x=[%.12f;%.12f], drop-out=%d",
+                y,
+                x1 / (double)ras.precision,
+                x2 / (double)ras.precision,
+                dropOutControl ));
+
     /* Drop-out control */
 
     e1 = TRUNC( CEILING( x1 ) );
@@ -2303,7 +2215,7 @@
 
     if ( e2 >= 0 && e1 < ras.bWidth )
     {
-      int   c1, c2;
+      Int   c1, c2;
       Byte  f1, f2;
 
 
@@ -2312,17 +2224,14 @@
       if ( e2 >= ras.bWidth )
         e2 = ras.bWidth - 1;
 
+      FT_TRACE7(( " -> x=[%d;%d]", e1, e2 ));
+
       c1 = (Short)( e1 >> 3 );
       c2 = (Short)( e2 >> 3 );
 
       f1 = (Byte)  ( 0xFF >> ( e1 & 7 ) );
       f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) );
 
-      if ( ras.gray_min_x > c1 )
-        ras.gray_min_x = (short)c1;
-      if ( ras.gray_max_x < c2 )
-        ras.gray_max_x = (short)c2;
-
       target = ras.bTarget + ras.traceOfs + c1;
       c2 -= c1;
 
@@ -2344,6 +2253,8 @@
       else
         *target |= ( f1 & f2 );
     }
+
+    FT_TRACE7(( "\n" ));
   }
 
 
@@ -2358,6 +2269,11 @@
     Short  c1, f1;
 
 
+    FT_TRACE7(( "  y=%d x=[%.12f;%.12f]",
+                y,
+                x1 / (double)ras.precision,
+                x2 / (double)ras.precision ));
+
     /* Drop-out control */
 
     /*   e2            x2                    x1           e1   */
@@ -2390,6 +2306,8 @@
       Int  dropOutControl = left->flags & 7;
 
 
+      FT_TRACE7(( ", drop-out=%d", dropOutControl ));
+
       if ( e1 == e2 + ras.precision )
       {
         switch ( dropOutControl )
@@ -2436,14 +2354,14 @@
                left->height <= 0                  &&
                !( left->flags & Overshoot_Top   &&
                   x2 - x1 >= ras.precision_half ) )
-            return;
+            goto Exit;
 
           /* lower stub test */
           if ( right->next == left                 &&
                left->start == y                    &&
                !( left->flags & Overshoot_Bottom &&
                   x2 - x1 >= ras.precision_half  ) )
-            return;
+            goto Exit;
 
           if ( dropOutControl == 1 )
             pxl = e2;
@@ -2452,7 +2370,7 @@
           break;
 
         default: /* modes 2, 3, 6, 7 */
-          return;  /* no drop-out control */
+          goto Exit;  /* no drop-out control */
         }
 
         /* undocumented but confirmed: If the drop-out would result in a  */
@@ -2473,26 +2391,26 @@
 
         if ( e1 >= 0 && e1 < ras.bWidth                      &&
              ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) )
-          return;
+          goto Exit;
       }
       else
-        return;
+        goto Exit;
     }
 
     e1 = TRUNC( pxl );
 
     if ( e1 >= 0 && e1 < ras.bWidth )
     {
+      FT_TRACE7(( " -> x=%d (drop-out)", e1 ));
+
       c1 = (Short)( e1 >> 3 );
       f1 = (Short)( e1 & 7 );
 
-      if ( ras.gray_min_x > c1 )
-        ras.gray_min_x = c1;
-      if ( ras.gray_max_x < c1 )
-        ras.gray_max_x = c1;
-
       ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 );
     }
+
+  Exit:
+    FT_TRACE7(( "\n" ));
   }
 
 
@@ -2539,32 +2457,39 @@
       Long  e1, e2;
 
 
+      FT_TRACE7(( "  x=%d y=[%.12f;%.12f]",
+                  y,
+                  x1 / (double)ras.precision,
+                  x2 / (double)ras.precision ));
+
       e1 = CEILING( x1 );
       e2 = FLOOR  ( x2 );
 
       if ( e1 == e2 )
       {
-        Byte   f1;
-        PByte  bits;
-
-
-        bits = ras.bTarget + ( y >> 3 );
-        f1   = (Byte)( 0x80 >> ( y & 7 ) );
-
         e1 = TRUNC( e1 );
 
-        if ( e1 >= 0 && e1 < ras.target.rows )
+        if ( e1 >= 0 && (ULong)e1 < ras.target.rows )
         {
+          Byte   f1;
+          PByte  bits;
           PByte  p;
 
 
-          p = bits - e1 * ras.target.pitch;
+          FT_TRACE7(( " -> y=%d (drop-out)", e1 ));
+
+          bits = ras.bTarget + ( y >> 3 );
+          f1   = (Byte)( 0x80 >> ( y & 7 ) );
+          p    = bits - e1 * ras.target.pitch;
+
           if ( ras.target.pitch > 0 )
-            p += ( ras.target.rows - 1 ) * ras.target.pitch;
+            p += (Long)( ras.target.rows - 1 ) * ras.target.pitch;
 
           p[0] |= f1;
         }
       }
+
+      FT_TRACE7(( "\n" ));
     }
   }
 
@@ -2581,6 +2506,11 @@
     Byte   f1;
 
 
+    FT_TRACE7(( "  x=%d y=[%.12f;%.12f]",
+                y,
+                x1 / (double)ras.precision,
+                x2 / (double)ras.precision ));
+
     /* During the horizontal sweep, we only take care of drop-outs */
 
     /* e1     +       <-- pixel center */
@@ -2602,6 +2532,8 @@
       Int  dropOutControl = left->flags & 7;
 
 
+      FT_TRACE7(( ", dropout=%d", dropOutControl ));
+
       if ( e1 == e2 + ras.precision )
       {
         switch ( dropOutControl )
@@ -2623,14 +2555,14 @@
                left->height <= 0                  &&
                !( left->flags & Overshoot_Top   &&
                   x2 - x1 >= ras.precision_half ) )
-            return;
+            goto Exit;
 
           /* leftmost stub test */
           if ( right->next == left                 &&
                left->start == y                    &&
                !( left->flags & Overshoot_Bottom &&
                   x2 - x1 >= ras.precision_half  ) )
-            return;
+            goto Exit;
 
           if ( dropOutControl == 1 )
             pxl = e2;
@@ -2639,7 +2571,7 @@
           break;
 
         default: /* modes 2, 3, 6, 7 */
-          return;  /* no drop-out control */
+          goto Exit;  /* no drop-out control */
         }
 
         /* undocumented but confirmed: If the drop-out would result in a  */
@@ -2647,7 +2579,7 @@
         /* bounding box instead                                           */
         if ( pxl < 0 )
           pxl = e1;
-        else if ( TRUNC( pxl ) >= ras.target.rows )
+        else if ( (ULong)( TRUNC( pxl ) ) >= ras.target.rows )
           pxl = e2;
 
         /* check that the other pixel isn't set */
@@ -2660,30 +2592,35 @@
 
         bits -= e1 * ras.target.pitch;
         if ( ras.target.pitch > 0 )
-          bits += ( ras.target.rows - 1 ) * ras.target.pitch;
+          bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch;
 
-        if ( e1 >= 0              &&
-             e1 < ras.target.rows &&
-             *bits & f1           )
-          return;
+        if ( e1 >= 0                     &&
+             (ULong)e1 < ras.target.rows &&
+             *bits & f1                  )
+          goto Exit;
       }
       else
-        return;
+        goto Exit;
     }
 
-    bits = ras.bTarget + ( y >> 3 );
-    f1   = (Byte)( 0x80 >> ( y & 7 ) );
-
     e1 = TRUNC( pxl );
 
-    if ( e1 >= 0 && e1 < ras.target.rows )
+    if ( e1 >= 0 && (ULong)e1 < ras.target.rows )
     {
+      FT_TRACE7(( " -> y=%d (drop-out)", e1 ));
+
+      bits  = ras.bTarget + ( y >> 3 );
+      f1    = (Byte)( 0x80 >> ( y & 7 ) );
       bits -= e1 * ras.target.pitch;
+
       if ( ras.target.pitch > 0 )
-        bits += ( ras.target.rows - 1 ) * ras.target.pitch;
+        bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch;
 
       bits[0] |= f1;
     }
+
+  Exit:
+    FT_TRACE7(( "\n" ));
   }
 
 
@@ -2695,249 +2632,6 @@
   }
 
 
-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*  Vertical Gray Sweep Procedure Set                                    */
-  /*                                                                       */
-  /*  These two routines are used during the vertical gray-levels sweep    */
-  /*  phase by the generic Draw_Sweep() function.                          */
-  /*                                                                       */
-  /*  NOTES                                                                */
-  /*                                                                       */
-  /*  - The target pixmap's width *must* be a multiple of 4.               */
-  /*                                                                       */
-  /*  - You have to use the function Vertical_Sweep_Span() for the gray    */
-  /*    span call.                                                         */
-  /*                                                                       */
-  /*************************************************************************/
-
-  static void
-  Vertical_Gray_Sweep_Init( RAS_ARGS Short*  min,
-                                     Short*  max )
-  {
-    Long  pitch, byte_len;
-
-
-    *min = *min & -2;
-    *max = ( *max + 3 ) & -2;
-
-    ras.traceOfs  = 0;
-    pitch         = ras.target.pitch;
-    byte_len      = -pitch;
-    ras.traceIncr = (Short)byte_len;
-    ras.traceG    = ( *min / 2 ) * byte_len;
-
-    if ( pitch > 0 )
-    {
-      ras.traceG += ( ras.target.rows - 1 ) * pitch;
-      byte_len    = -byte_len;
-    }
-
-    ras.gray_min_x =  (Short)byte_len;
-    ras.gray_max_x = -(Short)byte_len;
-  }
-
-
-  static void
-  Vertical_Gray_Sweep_Step( RAS_ARG )
-  {
-    short*  count = (short*)count_table;
-    Byte*   grays;
-
-
-    ras.traceOfs += ras.gray_width;
-
-    if ( ras.traceOfs > ras.gray_width )
-    {
-      PByte  pix;
-
-
-      pix   = ras.gTarget + ras.traceG + ras.gray_min_x * 4;
-      grays = ras.grays;
-
-      if ( ras.gray_max_x >= 0 )
-      {
-        Long  last_pixel = ras.target.width - 1;
-        Int   last_cell  = last_pixel >> 2;
-        Int   last_bit   = last_pixel & 3;
-        Bool  over       = 0;
-
-        Int    c1, c2;
-        PByte  bit, bit2;
-
-
-        if ( ras.gray_max_x >= last_cell && last_bit != 3 )
-        {
-          ras.gray_max_x = last_cell - 1;
-          over = 1;
-        }
-
-        if ( ras.gray_min_x < 0 )
-          ras.gray_min_x = 0;
-
-        bit  = ras.bTarget + ras.gray_min_x;
-        bit2 = bit + ras.gray_width;
-
-        c1 = ras.gray_max_x - ras.gray_min_x;
-
-        while ( c1 >= 0 )
-        {
-          c2 = count[*bit] + count[*bit2];
-
-          if ( c2 )
-          {
-            pix[0] = grays[(c2 >> 12) & 0x000F];
-            pix[1] = grays[(c2 >> 8 ) & 0x000F];
-            pix[2] = grays[(c2 >> 4 ) & 0x000F];
-            pix[3] = grays[ c2        & 0x000F];
-
-            *bit  = 0;
-            *bit2 = 0;
-          }
-
-          bit++;
-          bit2++;
-          pix += 4;
-          c1--;
-        }
-
-        if ( over )
-        {
-          c2 = count[*bit] + count[*bit2];
-          if ( c2 )
-          {
-            switch ( last_bit )
-            {
-            case 2:
-              pix[2] = grays[(c2 >> 4 ) & 0x000F];
-            case 1:
-              pix[1] = grays[(c2 >> 8 ) & 0x000F];
-            default:
-              pix[0] = grays[(c2 >> 12) & 0x000F];
-            }
-
-            *bit  = 0;
-            *bit2 = 0;
-          }
-        }
-      }
-
-      ras.traceOfs = 0;
-      ras.traceG  += ras.traceIncr;
-
-      ras.gray_min_x =  32000;
-      ras.gray_max_x = -32000;
-    }
-  }
-
-
-  static void
-  Horizontal_Gray_Sweep_Span( RAS_ARGS Short       y,
-                                       FT_F26Dot6  x1,
-                                       FT_F26Dot6  x2,
-                                       PProfile    left,
-                                       PProfile    right )
-  {
-    /* nothing, really */
-    FT_UNUSED_RASTER;
-    FT_UNUSED( y );
-    FT_UNUSED( x1 );
-    FT_UNUSED( x2 );
-    FT_UNUSED( left );
-    FT_UNUSED( right );
-  }
-
-
-  static void
-  Horizontal_Gray_Sweep_Drop( RAS_ARGS Short       y,
-                                       FT_F26Dot6  x1,
-                                       FT_F26Dot6  x2,
-                                       PProfile    left,
-                                       PProfile    right )
-  {
-    Long   e1, e2;
-    PByte  pixel;
-
-
-    /* During the horizontal sweep, we only take care of drop-outs */
-
-    e1 = CEILING( x1 );
-    e2 = FLOOR  ( x2 );
-
-    if ( e1 > e2 )
-    {
-      Int  dropOutControl = left->flags & 7;
-
-
-      if ( e1 == e2 + ras.precision )
-      {
-        switch ( dropOutControl )
-        {
-        case 0: /* simple drop-outs including stubs */
-          e1 = e2;
-          break;
-
-        case 4: /* smart drop-outs including stubs */
-          e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
-          break;
-
-        case 1: /* simple drop-outs excluding stubs */
-        case 5: /* smart drop-outs excluding stubs  */
-          /* see Vertical_Sweep_Drop for details */
-
-          /* rightmost stub test */
-          if ( left->next == right && left->height <= 0 )
-            return;
-
-          /* leftmost stub test */
-          if ( right->next == left && left->start == y )
-            return;
-
-          if ( dropOutControl == 1 )
-            e1 = e2;
-          else
-            e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
-
-          break;
-
-        default: /* modes 2, 3, 6, 7 */
-          return;  /* no drop-out control */
-        }
-      }
-      else
-        return;
-    }
-
-    if ( e1 >= 0 )
-    {
-      Byte  color;
-
-
-      if ( x2 - x1 >= ras.precision_half )
-        color = ras.grays[2];
-      else
-        color = ras.grays[1];
-
-      e1 = TRUNC( e1 ) / 2;
-      if ( e1 < ras.target.rows )
-      {
-        pixel = ras.gTarget - e1 * ras.target.pitch + y / 2;
-        if ( ras.target.pitch > 0 )
-          pixel += ( ras.target.rows - 1 ) * ras.target.pitch;
-
-        if ( pixel[0] == ras.grays[0] )
-          pixel[0] = color;
-      }
-    }
-  }
-
-
-#endif /* FT_RASTER_OPTION_ANTI_ALIASING */
-
-
   /*************************************************************************/
   /*                                                                       */
   /*  Generic Sweep Drawing routine                                        */
@@ -3007,7 +2701,7 @@
 
     while ( P )
     {
-      P->countL = (UShort)( P->start - min_Y );
+      P->countL = P->start - min_Y;
       P = P->link;
     }
 
@@ -3270,7 +2964,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF( FT_Error )
+  static FT_Error
   Render_Glyph( RAS_ARG )
   {
     FT_Error  error;
@@ -3293,10 +2987,12 @@
         ras.dropOutControl += 1;
     }
 
-    ras.second_pass = (FT_Byte)( !( ras.outline.flags &
-                                    FT_OUTLINE_SINGLE_PASS ) );
+    ras.second_pass = (Bool)( !( ras.outline.flags      &
+                                 FT_OUTLINE_SINGLE_PASS ) );
 
     /* Vertical Sweep */
+    FT_TRACE7(( "Vertical pass (ftraster)\n" ));
+
     ras.Proc_Sweep_Init = Vertical_Sweep_Init;
     ras.Proc_Sweep_Span = Vertical_Sweep_Span;
     ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
@@ -3304,9 +3000,9 @@
 
     ras.band_top            = 0;
     ras.band_stack[0].y_min = 0;
-    ras.band_stack[0].y_max = (short)( ras.target.rows - 1 );
+    ras.band_stack[0].y_max = (Short)( ras.target.rows - 1 );
 
-    ras.bWidth  = (unsigned short)ras.target.width;
+    ras.bWidth  = (UShort)ras.target.width;
     ras.bTarget = (Byte*)ras.target.buffer;
 
     if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 )
@@ -3315,6 +3011,8 @@
     /* Horizontal Sweep */
     if ( ras.second_pass && ras.dropOutControl != 2 )
     {
+      FT_TRACE7(( "Horizontal pass (ftraster)\n" ));
+
       ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
       ras.Proc_Sweep_Span = Horizontal_Sweep_Span;
       ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop;
@@ -3322,7 +3020,7 @@
 
       ras.band_top            = 0;
       ras.band_stack[0].y_min = 0;
-      ras.band_stack[0].y_max = (short)( ras.target.width - 1 );
+      ras.band_stack[0].y_max = (Short)( ras.target.width - 1 );
 
       if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 )
         return error;
@@ -3332,118 +3030,10 @@
   }
 
 
-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Render_Gray_Glyph                                                  */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Render a glyph with grayscaling.  Sub-banding if needed.           */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  FT_LOCAL_DEF( FT_Error )
-  Render_Gray_Glyph( RAS_ARG )
-  {
-    Long      pixel_width;
-    FT_Error  error;
-
-
-    Set_High_Precision( RAS_VARS ras.outline.flags &
-                                 FT_OUTLINE_HIGH_PRECISION );
-    ras.scale_shift = ras.precision_shift + 1;
-
-    if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )
-      ras.dropOutControl = 2;
-    else
-    {
-      if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS )
-        ras.dropOutControl = 4;
-      else
-        ras.dropOutControl = 0;
-
-      if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) )
-        ras.dropOutControl += 1;
-    }
-
-    ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS );
-
-    /* Vertical Sweep */
-
-    ras.band_top            = 0;
-    ras.band_stack[0].y_min = 0;
-    ras.band_stack[0].y_max = 2 * ras.target.rows - 1;
-
-    ras.bWidth  = ras.gray_width;
-    pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 );
-
-    if ( ras.bWidth > pixel_width )
-      ras.bWidth = pixel_width;
-
-    ras.bWidth  = ras.bWidth * 8;
-    ras.bTarget = (Byte*)ras.gray_lines;
-    ras.gTarget = (Byte*)ras.target.buffer;
-
-    ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init;
-    ras.Proc_Sweep_Span = Vertical_Sweep_Span;
-    ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
-    ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step;
-
-    error = Render_Single_Pass( RAS_VARS 0 );
-    if ( error )
-      return error;
-
-    /* Horizontal Sweep */
-    if ( ras.second_pass && ras.dropOutControl != 2 )
-    {
-      ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
-      ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span;
-      ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop;
-      ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
-
-      ras.band_top            = 0;
-      ras.band_stack[0].y_min = 0;
-      ras.band_stack[0].y_max = ras.target.width * 2 - 1;
-
-      error = Render_Single_Pass( RAS_VARS 1 );
-      if ( error )
-        return error;
-    }
-
-    return Raster_Err_None;
-  }
-
-#else /* !FT_RASTER_OPTION_ANTI_ALIASING */
-
-  FT_LOCAL_DEF( FT_Error )
-  Render_Gray_Glyph( RAS_ARG )
-  {
-    FT_UNUSED_RASTER;
-
-    return FT_THROW( Unsupported );
-  }
-
-#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */
-
-
   static void
   ft_black_init( black_PRaster  raster )
   {
-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
-    FT_UInt  n;
-
-
-    /* set default 5-levels gray palette */
-    for ( n = 0; n < 5; n++ )
-      raster->grays[n] = n * 255 / 4;
-
-    raster->gray_width = RASTER_GRAY_LINES / 2;
-#else
     FT_UNUSED( raster );
-#endif
   }
 
 
@@ -3518,54 +3108,24 @@
   static void
   ft_black_reset( black_PRaster  raster,
                   char*          pool_base,
-                  long           pool_size )
+                  Long           pool_size )
   {
-    if ( raster )
-    {
-      if ( pool_base && pool_size >= (long)sizeof ( black_TWorker ) + 2048 )
-      {
-        black_PWorker  worker = (black_PWorker)pool_base;
-
-
-        raster->buffer      = pool_base + ( ( sizeof ( *worker ) + 7 ) & ~7 );
-        raster->buffer_size = (long)( pool_base + pool_size -
-                                        (char*)raster->buffer );
-        raster->worker      = worker;
-      }
-      else
-      {
-        raster->buffer      = NULL;
-        raster->buffer_size = 0;
-        raster->worker      = NULL;
-      }
-    }
+    FT_UNUSED( raster );
+    FT_UNUSED( pool_base );
+    FT_UNUSED( pool_size );
   }
 
 
-  static void
+  static int
   ft_black_set_mode( black_PRaster  raster,
-                     unsigned long  mode,
+                     ULong          mode,
                      const char*    palette )
   {
-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
-
-    if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) )
-    {
-      /* set 5-levels gray palette */
-      raster->grays[0] = palette[0];
-      raster->grays[1] = palette[1];
-      raster->grays[2] = palette[2];
-      raster->grays[3] = palette[3];
-      raster->grays[4] = palette[4];
-    }
-
-#else
-
     FT_UNUSED( raster );
     FT_UNUSED( mode );
     FT_UNUSED( palette );
 
-#endif
+    return 0;
   }
 
 
@@ -3575,10 +3135,13 @@
   {
     const FT_Outline*  outline    = (const FT_Outline*)params->source;
     const FT_Bitmap*   target_map = params->target;
-    black_PWorker      worker;
+
+    black_TWorker  worker[1];
+
+    Long  buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( Long )];
 
 
-    if ( !raster || !raster->buffer || !raster->buffer_size )
+    if ( !raster )
       return FT_THROW( Not_Ini );
 
     if ( !outline )
@@ -3595,12 +3158,13 @@
            outline->contours[outline->n_contours - 1] + 1 )
       return FT_THROW( Invalid );
 
-    worker = raster->worker;
-
     /* this version of the raster does not support direct rendering, sorry */
     if ( params->flags & FT_RASTER_FLAG_DIRECT )
       return FT_THROW( Unsupported );
 
+    if ( params->flags & FT_RASTER_FLAG_AA )
+      return FT_THROW( Unsupported );
+
     if ( !target_map )
       return FT_THROW( Invalid );
 
@@ -3614,30 +3178,23 @@
     ras.outline = *outline;
     ras.target  = *target_map;
 
-    worker->buff       = (PLong) raster->buffer;
-    worker->sizeBuff   = worker->buff +
-                           raster->buffer_size / sizeof ( Long );
-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
-    worker->grays      = raster->grays;
-    worker->gray_width = raster->gray_width;
+    worker->buff     = buffer;
+    worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */
 
-    FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 );
-#endif
-
-    return ( params->flags & FT_RASTER_FLAG_AA )
-           ? Render_Gray_Glyph( RAS_VAR )
-           : Render_Glyph( RAS_VAR );
+    return Render_Glyph( RAS_VAR );
   }
 
 
-  FT_DEFINE_RASTER_FUNCS( ft_standard_raster,
+  FT_DEFINE_RASTER_FUNCS(
+    ft_standard_raster,
+
     FT_GLYPH_FORMAT_OUTLINE,
+
     (FT_Raster_New_Func)     ft_black_new,
     (FT_Raster_Reset_Func)   ft_black_reset,
     (FT_Raster_Set_Mode_Func)ft_black_set_mode,
     (FT_Raster_Render_Func)  ft_black_render,
-    (FT_Raster_Done_Func)    ft_black_done
-  )
+    (FT_Raster_Done_Func)    ft_black_done )
 
 
 /* END */
diff --git a/src/raster/ftraster.h b/src/raster/ftraster.h
index 80fe46d..a270d48 100644
--- a/src/raster/ftraster.h
+++ b/src/raster/ftraster.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph rasterizer (specification).                       */
 /*                                                                         */
-/*  Copyright 1996-2001 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used        */
diff --git a/src/raster/ftrend1.c b/src/raster/ftrend1.c
index aa7f6d5..f314392 100644
--- a/src/raster/ftrend1.c
+++ b/src/raster/ftrend1.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph rasterizer interface (body).                      */
 /*                                                                         */
-/*  Copyright 1996-2003, 2005, 2006, 2011, 2013 by                         */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -104,7 +104,7 @@
   {
     FT_Error     error;
     FT_Outline*  outline;
-    FT_BBox      cbox;
+    FT_BBox      cbox, cbox0;
     FT_UInt      width, height, pitch;
     FT_Bitmap*   bitmap;
     FT_Memory    memory;
@@ -120,38 +120,11 @@
     }
 
     /* check rendering mode */
-#ifndef FT_CONFIG_OPTION_PIC
     if ( mode != FT_RENDER_MODE_MONO )
     {
       /* raster1 is only capable of producing monochrome bitmaps */
-      if ( render->clazz == &ft_raster1_renderer_class )
-        return FT_THROW( Cannot_Render_Glyph );
+      return FT_THROW( Cannot_Render_Glyph );
     }
-    else
-    {
-      /* raster5 is only capable of producing 5-gray-levels bitmaps */
-      if ( render->clazz == &ft_raster5_renderer_class )
-        return FT_THROW( Cannot_Render_Glyph );
-    }
-#else /* FT_CONFIG_OPTION_PIC */
-    /* When PIC is enabled, we cannot get to the class object      */
-    /* so instead we check the final character in the class name   */
-    /* ("raster5" or "raster1"). Yes this is a hack.               */
-    /* The "correct" thing to do is have different render function */
-    /* for each of the classes.                                    */
-    if ( mode != FT_RENDER_MODE_MONO )
-    {
-      /* raster1 is only capable of producing monochrome bitmaps */
-      if ( render->clazz->root.module_name[6] == '1' )
-        return FT_THROW( Cannot_Render_Glyph );
-    }
-    else
-    {
-      /* raster5 is only capable of producing 5-gray-levels bitmaps */
-      if ( render->clazz->root.module_name[6] == '5' )
-        return FT_THROW( Cannot_Render_Glyph );
-    }
-#endif /* FT_CONFIG_OPTION_PIC */
 
     outline = &slot->outline;
 
@@ -160,14 +133,14 @@
       FT_Outline_Translate( outline, origin->x, origin->y );
 
     /* compute the control box, and grid fit it */
-    FT_Outline_Get_CBox( outline, &cbox );
+    FT_Outline_Get_CBox( outline, &cbox0 );
 
     /* undocumented but confirmed: bbox values get rounded */
 #if 1
-    cbox.xMin = FT_PIX_ROUND( cbox.xMin );
-    cbox.yMin = FT_PIX_ROUND( cbox.yMin );
-    cbox.xMax = FT_PIX_ROUND( cbox.xMax );
-    cbox.yMax = FT_PIX_ROUND( cbox.yMax );
+    cbox.xMin = FT_PIX_ROUND( cbox0.xMin );
+    cbox.yMin = FT_PIX_ROUND( cbox0.yMin );
+    cbox.xMax = FT_PIX_ROUND( cbox0.xMax );
+    cbox.yMax = FT_PIX_ROUND( cbox0.yMax );
 #else
     cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
     cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
@@ -175,8 +148,28 @@
     cbox.yMax = FT_PIX_CEIL( cbox.yMax );
 #endif
 
+    /* If either `width' or `height' round to 0, try    */
+    /* explicitly rounding up/down.  In the case of     */
+    /* glyphs containing only one very narrow feature,  */
+    /* this gives the drop-out compensation in the scan */
+    /* conversion code a chance to do its stuff.        */
     width  = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 );
+    if ( width == 0 )
+    {
+      cbox.xMin = FT_PIX_FLOOR( cbox0.xMin );
+      cbox.xMax = FT_PIX_CEIL( cbox0.xMax );
+
+      width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 );
+    }
+
     height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 );
+    if ( height == 0 )
+    {
+      cbox.yMin = FT_PIX_FLOOR( cbox0.yMin );
+      cbox.yMax = FT_PIX_CEIL( cbox0.yMax );
+
+      height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 );
+    }
 
     if ( width > FT_USHORT_MAX || height > FT_USHORT_MAX )
     {
@@ -194,23 +187,12 @@
       slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
     }
 
-    /* allocate new one, depends on pixel format */
-    if ( !( mode & FT_RENDER_MODE_MONO ) )
-    {
-      /* we pad to 32 bits, only for backwards compatibility with FT 1.x */
-      pitch              = FT_PAD_CEIL( width, 4 );
-      bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
-      bitmap->num_grays  = 256;
-    }
-    else
-    {
-      pitch              = ( ( width + 15 ) >> 4 ) << 1;
-      bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
-    }
+    pitch              = ( ( width + 15 ) >> 4 ) << 1;
+    bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
 
     bitmap->width = width;
     bitmap->rows  = height;
-    bitmap->pitch = pitch;
+    bitmap->pitch = (int)pitch;
 
     if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) )
       goto Exit;
@@ -225,9 +207,6 @@
     params.source = outline;
     params.flags  = 0;
 
-    if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY )
-      params.flags |= FT_RASTER_FLAG_AA;
-
     /* render outline into the bitmap */
     error = render->raster_render( render->raster, &params );
 
@@ -272,35 +251,4 @@
   )
 
 
-  /* This renderer is _NOT_ part of the default modules; you will need */
-  /* to register it by hand in your application.  It should only be    */
-  /* used for backwards-compatibility with FT 1.x anyway.              */
-  /*                                                                   */
-  FT_DEFINE_RENDERER( ft_raster5_renderer_class,
-
-      FT_MODULE_RENDERER,
-      sizeof ( FT_RendererRec ),
-
-      "raster5",
-      0x10000L,
-      0x20000L,
-
-      0,    /* module specific interface */
-
-      (FT_Module_Constructor)ft_raster1_init,
-      (FT_Module_Destructor) 0,
-      (FT_Module_Requester)  0
-    ,
-
-    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_Raster_Funcs*)    &FT_STANDARD_RASTER_GET
-  )
-
-
 /* END */
diff --git a/src/raster/ftrend1.h b/src/raster/ftrend1.h
index 4cf1286..c367260 100644
--- a/src/raster/ftrend1.h
+++ b/src/raster/ftrend1.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph rasterizer interface (specification).             */
 /*                                                                         */
-/*  Copyright 1996-2001 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/raster/raster.c b/src/raster/raster.c
index 1202a11..21bb16d 100644
--- a/src/raster/raster.c
+++ b/src/raster/raster.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType monochrome rasterer module component (body only).           */
 /*                                                                         */
-/*  Copyright 1996-2001 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/raster/rasterrs.h b/src/raster/rasterrs.h
index ab85c00..e7f00bc 100644
--- a/src/raster/rasterrs.h
+++ b/src/raster/rasterrs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    monochrome renderer error codes (specification only).                */
 /*                                                                         */
-/*  Copyright 2001, 2012 by                                                */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/raster/rastpic.c b/src/raster/rastpic.c
index 5e9f7cc..fe58c99 100644
--- a/src/raster/rastpic.c
+++ b/src/raster/rastpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for raster module.   */
 /*                                                                         */
-/*  Copyright 2009, 2010, 2012, 2013 by                                    */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/raster/rastpic.h b/src/raster/rastpic.h
index e0ddba6..a875884 100644
--- a/src/raster/rastpic.h
+++ b/src/raster/rastpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for raster module.   */
 /*                                                                         */
-/*  Copyright 2009 by                                                      */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/pngshim.c b/src/sfnt/pngshim.c
index 9afbe5a..ea60452 100644
--- a/src/sfnt/pngshim.c
+++ b/src/sfnt/pngshim.c
@@ -4,7 +4,8 @@
 /*                                                                         */
 /*    PNG Bitmap glyph support.                                            */
 /*                                                                         */
-/*  Copyright 2013, 2014 by Google, Inc.                                   */
+/*  Copyright 2013-2015 by                                                 */
+/*  Google, Inc.                                                           */
 /*  Written by Stuart Gill and Behdad Esfahbod.                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -36,11 +37,11 @@
   /* This code is freely based on cairo-png.c.  There's so many ways */
   /* to call libpng, and the way cairo does it is defacto standard.  */
 
-  static int
-  multiply_alpha( int  alpha,
-                  int  color )
+  static unsigned int
+  multiply_alpha( unsigned int  alpha,
+                  unsigned int  color )
   {
-    int  temp = ( alpha * color ) + 0x80;
+    unsigned int  temp = alpha * color + 0x80;
 
 
     return ( temp + ( temp >> 8 ) ) >> 8;
@@ -81,10 +82,10 @@
           blue  = multiply_alpha( alpha, blue  );
         }
 
-        base[0] = blue;
-        base[1] = green;
-        base[2] = red;
-        base[3] = alpha;
+        base[0] = (unsigned char)blue;
+        base[1] = (unsigned char)green;
+        base[2] = (unsigned char)red;
+        base[3] = (unsigned char)alpha;
       }
     }
   }
@@ -109,9 +110,9 @@
       unsigned int    blue  = base[2];
 
 
-      base[0] = blue;
-      base[1] = green;
-      base[2] = red;
+      base[0] = (unsigned char)blue;
+      base[1] = (unsigned char)green;
+      base[2] = (unsigned char)red;
       base[3] = 0xFF;
     }
   }
@@ -205,11 +206,11 @@
       goto Exit;
     }
 
-    if ( !populate_map_and_metrics                   &&
-         ( x_offset + metrics->width  > map->width ||
-           y_offset + metrics->height > map->rows  ||
-           pix_bits != 32                          ||
-           map->pixel_mode != FT_PIXEL_MODE_BGRA   ) )
+    if ( !populate_map_and_metrics                            &&
+         ( (FT_UInt)x_offset + metrics->width  > map->width ||
+           (FT_UInt)y_offset + metrics->height > map->rows  ||
+           pix_bits != 32                                   ||
+           map->pixel_mode != FT_PIXEL_MODE_BGRA            ) )
     {
       error = FT_THROW( Invalid_Argument );
       goto Exit;
@@ -257,19 +258,27 @@
 
     if ( populate_map_and_metrics )
     {
-      FT_Long  size;
+      FT_ULong  size;
 
 
-      metrics->width  = (FT_Int)imgWidth;
-      metrics->height = (FT_Int)imgHeight;
+      metrics->width  = (FT_UShort)imgWidth;
+      metrics->height = (FT_UShort)imgHeight;
 
       map->width      = metrics->width;
       map->rows       = metrics->height;
       map->pixel_mode = FT_PIXEL_MODE_BGRA;
-      map->pitch      = map->width * 4;
+      map->pitch      = (int)( map->width * 4 );
       map->num_grays  = 256;
 
-      size = map->rows * map->pitch;
+      /* reject too large bitmaps similarly to the rasterizer */
+      if ( map->rows > 0x7FFF || map->width > 0x7FFF )
+      {
+        error = FT_THROW( Array_Too_Large );
+        goto DestroyExit;
+      }
+
+      /* this doesn't overflow: 0x7FFF * 0x7FFF * 4 < 2^32 */
+      size = map->rows * (FT_ULong)map->pitch;
 
       error = ft_glyphslot_alloc_bitmap( slot, size );
       if ( error )
diff --git a/src/sfnt/pngshim.h b/src/sfnt/pngshim.h
index dc9ecaf..4cc5c2b 100644
--- a/src/sfnt/pngshim.h
+++ b/src/sfnt/pngshim.h
@@ -4,7 +4,8 @@
 /*                                                                         */
 /*    PNG Bitmap glyph support.                                            */
 /*                                                                         */
-/*  Copyright 2013 by Google, Inc.                                         */
+/*  Copyright 2013-2015 by                                                 */
+/*  Google, Inc.                                                           */
 /*  Written by Stuart Gill and Behdad Esfahbod.                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
index e4fcda5..0948ad4 100644
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level SFNT driver interface (body).                             */
 /*                                                                         */
-/*  Copyright 1996-2007, 2009-2014 by                                      */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -75,36 +75,36 @@
 
     switch ( tag )
     {
-    case ft_sfnt_head:
+    case FT_SFNT_HEAD:
       table = &face->header;
       break;
 
-    case ft_sfnt_hhea:
+    case FT_SFNT_HHEA:
       table = &face->horizontal;
       break;
 
-    case ft_sfnt_vhea:
-      table = face->vertical_info ? &face->vertical : 0;
+    case FT_SFNT_VHEA:
+      table = face->vertical_info ? &face->vertical : NULL;
       break;
 
-    case ft_sfnt_os2:
-      table = face->os2.version == 0xFFFFU ? 0 : &face->os2;
+    case FT_SFNT_OS2:
+      table = face->os2.version == 0xFFFFU ? NULL : &face->os2;
       break;
 
-    case ft_sfnt_post:
+    case FT_SFNT_POST:
       table = &face->postscript;
       break;
 
-    case ft_sfnt_maxp:
+    case FT_SFNT_MAXP:
       table = &face->max_profile;
       break;
 
-    case ft_sfnt_pclt:
-      table = face->pclt.Version ? &face->pclt : 0;
+    case FT_SFNT_PCLT:
+      table = face->pclt.Version ? &face->pclt : NULL;
       break;
 
     default:
-      table = 0;
+      table = NULL;
     }
 
     return table;
@@ -266,7 +266,7 @@
       {
         FT_Stream   stream = face->name_table.stream;
         FT_String*  r      = (FT_String*)result;
-        FT_Byte*    p;
+        FT_Char*    p;
 
 
         if ( FT_STREAM_SEEK( name->stringOffset ) ||
@@ -280,11 +280,11 @@
           goto Exit;
         }
 
-        p = (FT_Byte*)stream->cursor;
+        p = (FT_Char*)stream->cursor;
 
         for ( ; len > 0; len--, p += 2 )
         {
-          if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 )
+          if ( p[0] == 0 && p[1] >= 32 )
             *r++ = p[1];
         }
         *r = '\0';
@@ -427,7 +427,7 @@
   sfnt_get_interface( FT_Module    module,
                       const char*  module_interface )
   {
-    /* SFNT_SERVICES_GET derefers `library' in PIC mode */
+    /* SFNT_SERVICES_GET dereferences `library' in PIC mode */
 #ifdef FT_CONFIG_OPTION_PIC
     FT_Library  library;
 
diff --git a/src/sfnt/sfdriver.h b/src/sfnt/sfdriver.h
index 5de25d5..944119c 100644
--- a/src/sfnt/sfdriver.h
+++ b/src/sfnt/sfdriver.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level SFNT driver interface (specification).                    */
 /*                                                                         */
-/*  Copyright 1996-2001 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/sferrors.h b/src/sfnt/sferrors.h
index e981e1d..e3bef3f 100644
--- a/src/sfnt/sferrors.h
+++ b/src/sfnt/sferrors.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    SFNT error codes (specification only).                               */
 /*                                                                         */
-/*  Copyright 2001, 2004, 2012, 2013 by                                    */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/sfnt.c b/src/sfnt/sfnt.c
index d62ed4e..0b8b5f4 100644
--- a/src/sfnt/sfnt.c
+++ b/src/sfnt/sfnt.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Single object library component.                                     */
 /*                                                                         */
-/*  Copyright 1996-2006, 2013 by                                           */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/sfntpic.c b/src/sfnt/sfntpic.c
index b3fb24b..2aaf4bc 100644
--- a/src/sfnt/sfntpic.c
+++ b/src/sfnt/sfntpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for sfnt module.     */
 /*                                                                         */
-/*  Copyright 2009, 2010, 2012, 2013 by                                    */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/sfntpic.h b/src/sfnt/sfntpic.h
index b09a914..563d634 100644
--- a/src/sfnt/sfntpic.h
+++ b/src/sfnt/sfntpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for sfnt module.     */
 /*                                                                         */
-/*  Copyright 2009, 2012 by                                                */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 44aa467..40c27fa 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    SFNT object management (base).                                       */
 /*                                                                         */
-/*  Copyright 1996-2008, 2010-2014 by                                      */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -376,8 +376,8 @@
     FT_FREE( stream->base );
 
     stream->size  = 0;
-    stream->base  = 0;
-    stream->close = 0;
+    stream->base  = NULL;
+    stream->close = NULL;
   }
 
 
@@ -567,8 +567,10 @@
 
 
       if ( table->Offset != woff_offset                         ||
-           table->Offset + table->CompLength > woff.length      ||
-           sfnt_offset + table->OrigLength > woff.totalSfntSize ||
+           table->CompLength > woff.length                      ||
+           table->Offset > woff.length - table->CompLength      ||
+           table->OrigLength > woff.totalSfntSize               ||
+           sfnt_offset > woff.totalSfntSize - table->OrigLength ||
            table->CompLength > table->OrigLength                )
       {
         error = FT_THROW( Invalid_Table );
@@ -578,8 +580,8 @@
       table->OrigOffset = sfnt_offset;
 
       /* The offsets must be multiples of 4. */
-      woff_offset += ( table->CompLength + 3 ) & ~3;
-      sfnt_offset += ( table->OrigLength + 3 ) & ~3;
+      woff_offset += ( table->CompLength + 3 ) & ~3U;
+      sfnt_offset += ( table->OrigLength + 3 ) & ~3U;
     }
 
     /*
@@ -607,7 +609,7 @@
     if ( woff.privOffset )
     {
       /* ... if it isn't the last block. */
-      woff_offset = ( woff_offset + 3 ) & ~3;
+      woff_offset = ( woff_offset + 3 ) & ~3U;
 
       if ( woff.privOffset != woff_offset                  ||
            woff.privOffset + woff.privLength > woff.length )
@@ -1016,7 +1018,6 @@
     if ( is_apple_sbix )
       has_outline = FALSE;
 
-
     /* if this font doesn't contain outlines, we try to load */
     /* a `bhed' table                                        */
     if ( !has_outline && sfnt->load_bhed )
@@ -1430,8 +1431,8 @@
         root->ascender  = face->horizontal.Ascender;
         root->descender = face->horizontal.Descender;
 
-        root->height = (FT_Short)( root->ascender - root->descender +
-                                   face->horizontal.Line_Gap );
+        root->height = root->ascender - root->descender +
+                       face->horizontal.Line_Gap;
 
         if ( !( root->ascender || root->descender ) )
         {
@@ -1442,23 +1443,24 @@
               root->ascender  = face->os2.sTypoAscender;
               root->descender = face->os2.sTypoDescender;
 
-              root->height = (FT_Short)( root->ascender - root->descender +
-                                         face->os2.sTypoLineGap );
+              root->height = root->ascender - root->descender +
+                             face->os2.sTypoLineGap;
             }
             else
             {
               root->ascender  =  (FT_Short)face->os2.usWinAscent;
               root->descender = -(FT_Short)face->os2.usWinDescent;
 
-              root->height = (FT_UShort)( root->ascender - root->descender );
+              root->height = root->ascender - root->descender;
             }
           }
         }
 
-        root->max_advance_width  = face->horizontal.advance_Width_Max;
-        root->max_advance_height = (FT_Short)( face->vertical_info
-                                     ? face->vertical.advance_Height_Max
-                                     : root->height );
+        root->max_advance_width  =
+          (FT_Short)face->horizontal.advance_Width_Max;
+        root->max_advance_height =
+          (FT_Short)( face->vertical_info ? face->vertical.advance_Height_Max
+                                          : root->height );
 
         /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */
         /* Adjust underline position from top edge to centre of     */
@@ -1568,7 +1570,7 @@
 
     FT_FREE( face->postscript_name );
 
-    face->sfnt = 0;
+    face->sfnt = NULL;
   }
 
 
diff --git a/src/sfnt/sfobjs.h b/src/sfnt/sfobjs.h
index 6241c93..77c7d92 100644
--- a/src/sfnt/sfobjs.h
+++ b/src/sfnt/sfobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    SFNT object management (specification).                              */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002 by                                           */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttbdf.c b/src/sfnt/ttbdf.c
index 9401dae..098b781 100644
--- a/src/sfnt/ttbdf.c
+++ b/src/sfnt/ttbdf.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType and OpenType embedded BDF properties (body).                */
 /*                                                                         */
-/*  Copyright 2005, 2006, 2010, 2013 by                                    */
+/*  Copyright 2005-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttbdf.h b/src/sfnt/ttbdf.h
index 48a10d6..fe4ba48 100644
--- a/src/sfnt/ttbdf.h
+++ b/src/sfnt/ttbdf.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType and OpenType embedded BDF properties (specification).       */
 /*                                                                         */
-/*  Copyright 2005 by                                                      */
+/*  Copyright 2005-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
index f9acf5d..815ee7c 100644
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType character mapping table (cmap) support (body).              */
 /*                                                                         */
-/*  Copyright 2002-2010, 2012-2014 by                                      */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -360,7 +360,7 @@
 
 
         ids = p - 2 + offset;
-        if ( ids < glyph_ids || ids + code_count*2 > table + length )
+        if ( ids < glyph_ids || ids + code_count * 2 > table + length )
           FT_INVALID_OFFSET;
 
         /* check glyph IDs */
@@ -375,7 +375,7 @@
             idx = TT_NEXT_USHORT( p );
             if ( idx != 0 )
             {
-              idx = ( idx + delta ) & 0xFFFFU;
+              idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
               if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )
                 FT_INVALID_GLYPH_ID;
             }
@@ -472,7 +472,7 @@
         idx = TT_PEEK_USHORT( p );
 
         if ( idx != 0 )
-          result = (FT_UInt)( idx + delta ) & 0xFFFFU;
+          result = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
       }
     }
     return result;
@@ -524,7 +524,7 @@
 
           if ( idx != 0 )
           {
-            gindex = ( idx + delta ) & 0xFFFFU;
+            gindex = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
             if ( gindex != 0 )
             {
               result = charcode;
@@ -786,7 +786,7 @@
 
             if ( gindex != 0 )
             {
-              gindex = (FT_UInt)( ( gindex + delta ) & 0xFFFFU );
+              gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
               if ( gindex != 0 )
               {
                 cmap->cur_charcode = charcode;
@@ -800,7 +800,7 @@
         {
           do
           {
-            FT_UInt  gindex = (FT_UInt)( ( charcode + delta ) & 0xFFFFU );
+            FT_UInt  gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
 
 
             if ( gindex != 0 )
@@ -845,9 +845,6 @@
     p      = table + 2;           /* skip format */
     length = TT_NEXT_USHORT( p );
 
-    if ( length < 16 )
-      FT_INVALID_TOO_SHORT;
-
     /* in certain fonts, the `length' field is invalid and goes */
     /* out of bound.  We try to correct this here...            */
     if ( table + length > valid->limit )
@@ -858,6 +855,9 @@
       length = (FT_UInt)( valid->limit - table );
     }
 
+    if ( length < 16 )
+      FT_INVALID_TOO_SHORT;
+
     p        = table + 6;
     num_segs = TT_NEXT_USHORT( p );   /* read segCountX2 */
 
@@ -993,7 +993,7 @@
               idx = FT_NEXT_USHORT( p );
               if ( idx != 0 )
               {
-                idx = (FT_UInt)( idx + delta ) & 0xFFFFU;
+                idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
 
                 if ( idx >= TT_VALID_GLYPH_COUNT( valid ) )
                   FT_INVALID_GLYPH_ID;
@@ -1090,10 +1090,10 @@
             p += offset + ( charcode - start ) * 2;
             gindex = TT_PEEK_USHORT( p );
             if ( gindex != 0 )
-              gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;
+              gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
           }
           else
-            gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU;
+            gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
 
           break;
         }
@@ -1294,10 +1294,10 @@
           p += offset + ( charcode - start ) * 2;
           gindex = TT_PEEK_USHORT( p );
           if ( gindex != 0 )
-            gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;
+            gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
         }
         else
-          gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU;
+          gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
 
         break;
       }
@@ -1669,7 +1669,8 @@
     p          = is32  + 8192;          /* skip `is32' array */
     num_groups = TT_NEXT_ULONG( p );
 
-    if ( p + num_groups * 12 > valid->limit )
+    /* p + num_groups * 12 > valid->limit ? */
+    if ( num_groups > (FT_UInt32)( valid->limit - p ) / 12 )
       FT_INVALID_TOO_SHORT;
 
     /* check groups, they must be in increasing order */
@@ -1694,7 +1695,12 @@
 
         if ( valid->level >= FT_VALIDATE_TIGHT )
         {
-          if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) )
+          FT_UInt32  d = end - start;
+
+
+          /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */
+          if ( d > TT_VALID_GLYPH_COUNT( valid )             ||
+               start_id >= TT_VALID_GLYPH_COUNT( valid ) - d )
             FT_INVALID_GLYPH_ID;
 
           count = (FT_UInt32)( end - start + 1 );
@@ -1892,7 +1898,9 @@
     count  = TT_NEXT_ULONG( p );
 
     if ( length > (FT_ULong)( valid->limit - table ) ||
-         length < 20 + count * 2                     )
+         /* length < 20 + count * 2 ? */
+         length < 20                                 ||
+         ( length - 20 ) / 2 < count                 )
       FT_INVALID_TOO_SHORT;
 
     /* check glyph indices */
@@ -2079,7 +2087,9 @@
     num_groups = TT_NEXT_ULONG( p );
 
     if ( length > (FT_ULong)( valid->limit - table ) ||
-         length < 16 + 12 * num_groups               )
+         /* length < 16 + 12 * num_groups ? */
+         length < 16                                 ||
+         ( length - 16 ) / 12 < num_groups           )
       FT_INVALID_TOO_SHORT;
 
     /* check groups, they must be in increasing order */
@@ -2101,7 +2111,12 @@
 
         if ( valid->level >= FT_VALIDATE_TIGHT )
         {
-          if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) )
+          FT_UInt32  d = end - start;
+
+
+          /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */
+          if ( d > TT_VALID_GLYPH_COUNT( valid )             ||
+               start_id >= TT_VALID_GLYPH_COUNT( valid ) - d )
             FT_INVALID_GLYPH_ID;
         }
 
@@ -2401,7 +2416,9 @@
     num_groups = TT_NEXT_ULONG( p );
 
     if ( length > (FT_ULong)( valid->limit - table ) ||
-         length < 16 + 12 * num_groups               )
+         /* length < 16 + 12 * num_groups ? */
+         length < 16                                 ||
+         ( length - 16 ) / 12 < num_groups           )
       FT_INVALID_TOO_SHORT;
 
     /* check groups, they must be in increasing order */
@@ -2787,7 +2804,9 @@
     num_selectors = TT_NEXT_ULONG( p );
 
     if ( length > (FT_ULong)( valid->limit - table ) ||
-         length < 10 + 11 * num_selectors            )
+         /* length < 10 + 11 * num_selectors ? */
+         length < 10                                 ||
+         ( length - 10 ) / 11 < num_selectors        )
       FT_INVALID_TOO_SHORT;
 
     /* check selectors, they must be in increasing order */
@@ -2823,7 +2842,8 @@
           FT_ULong  lastBase  = 0;
 
 
-          if ( defp + numRanges * 4 > valid->limit )
+          /* defp + numRanges * 4 > valid->limit ? */
+          if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 )
             FT_INVALID_TOO_SHORT;
 
           for ( i = 0; i < numRanges; ++i )
@@ -2850,7 +2870,8 @@
           FT_ULong  i, lastUni  = 0;
 
 
-          if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) )
+          /* numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ? */
+          if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 4 )
             FT_INVALID_TOO_SHORT;
 
           for ( i = 0; i < numMappings; ++i )
@@ -3475,20 +3496,12 @@
     {
       FT_ERROR(( "tt_face_build_cmaps:"
                  " unsupported `cmap' table format = %d\n",
-                 TT_PEEK_USHORT( p - 2) ));
+                 TT_PEEK_USHORT( p - 2 ) ));
       return FT_THROW( Invalid_Table );
     }
 
     num_cmaps = TT_NEXT_USHORT( p );
 
-#ifdef FT_MAX_CHARMAP_CACHEABLE
-    if ( num_cmaps > FT_MAX_CHARMAP_CACHEABLE )
-      FT_ERROR(( "tt_face_build_cmaps: too many cmap subtables (%d)\n"
-                 "                     subtable #%d and higher are loaded"
-                 "                     but cannot be searched\n",
-                 num_cmaps, FT_MAX_CHARMAP_CACHEABLE + 1 ));
-#endif
-
     for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- )
     {
       FT_CharMapRec  charmap;
diff --git a/src/sfnt/ttcmap.h b/src/sfnt/ttcmap.h
index 0fde167..b7ea8ee 100644
--- a/src/sfnt/ttcmap.h
+++ b/src/sfnt/ttcmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType character mapping table (cmap) support (specification).     */
 /*                                                                         */
-/*  Copyright 2002-2005, 2009, 2012 by                                     */
+/*  Copyright 2002-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttcmapc.h b/src/sfnt/ttcmapc.h
index 2ea2043..4a48940 100644
--- a/src/sfnt/ttcmapc.h
+++ b/src/sfnt/ttcmapc.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TT CMAP classes definitions (specification only).                    */
 /*                                                                         */
-/*  Copyright 2009 by                                                      */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttkern.c b/src/sfnt/ttkern.c
index 32c4008..4fccc53 100644
--- a/src/sfnt/ttkern.c
+++ b/src/sfnt/ttkern.c
@@ -5,7 +5,7 @@
 /*    Load the basic TrueType kerning table.  This doesn't handle          */
 /*    kerning data within the GPOS table at the moment.                    */
 /*                                                                         */
-/*  Copyright 1996-2007, 2009, 2010, 2013 by                               */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -99,7 +99,7 @@
       length   = FT_NEXT_USHORT( p );
       coverage = FT_NEXT_USHORT( p );
 
-      if ( length <= 6 )
+      if ( length <= 6 + 8 )
         break;
 
       p_next += length;
@@ -108,8 +108,8 @@
         p_next = p_limit;
 
       /* only use horizontal kerning tables */
-      if ( ( coverage & ~8 ) != 0x0001 ||
-           p + 8 > p_limit             )
+      if ( ( coverage & ~8U ) != 0x0001 ||
+           p + 8 > p_limit              )
         goto NextTable;
 
       num_pairs = FT_NEXT_USHORT( p );
diff --git a/src/sfnt/ttkern.h b/src/sfnt/ttkern.h
index df1da9b..89cb24f 100644
--- a/src/sfnt/ttkern.h
+++ b/src/sfnt/ttkern.h
@@ -5,7 +5,7 @@
 /*    Load the basic TrueType kerning table.  This doesn't handle          */
 /*    kerning data within the GPOS table at the moment.                    */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2005, 2007 by                               */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c
index 0a3cd29..ad2975d 100644
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -5,7 +5,7 @@
 /*    Load the basic TrueType tables, i.e., tables that can be either in   */
 /*    TTF or OTF fonts (body).                                             */
 /*                                                                         */
-/*  Copyright 1996-2010, 2012, 2013 by                                     */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -207,10 +207,24 @@
       }
 
       /* we ignore invalid tables */
-      if ( table.Offset + table.Length > stream->size )
-      {
-        FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
+
+      if ( table.Offset > stream->size )
         continue;
+      else if ( table.Length > stream->size - table.Offset )
+      {
+        /* Some tables have such a simple structure that clipping its     */
+        /* contents is harmless.  This also makes FreeType less sensitive */
+        /* to invalid table lengths (which programs like Acroread seem to */
+        /* ignore in general).                                            */
+
+        if ( table.Tag == TTAG_hmtx ||
+             table.Tag == TTAG_vmtx )
+          valid_entries++;
+        else
+        {
+          FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
+          continue;
+        }
       }
       else
         valid_entries++;
@@ -394,9 +408,38 @@
       entry->Offset   = FT_GET_ULONG();
       entry->Length   = FT_GET_ULONG();
 
-      /* ignore invalid tables */
-      if ( entry->Offset + entry->Length > stream->size )
+      /* ignore invalid tables that can't be sanitized */
+
+      if ( entry->Offset > stream->size )
         continue;
+      else if ( entry->Length > stream->size - entry->Offset )
+      {
+        if ( entry->Tag == TTAG_hmtx ||
+             entry->Tag == TTAG_vmtx )
+        {
+#ifdef FT_DEBUG_LEVEL_TRACE
+          FT_ULong  old_length = entry->Length;
+#endif
+
+
+          /* make metrics table length a multiple of 4 */
+          entry->Length = ( stream->size - entry->Offset ) & ~3U;
+
+          FT_TRACE2(( "  %c%c%c%c  %08lx  %08lx  %08lx"
+                      " (sanitized; original length %08lx)\n",
+                      (FT_Char)( entry->Tag >> 24 ),
+                      (FT_Char)( entry->Tag >> 16 ),
+                      (FT_Char)( entry->Tag >> 8  ),
+                      (FT_Char)( entry->Tag       ),
+                      entry->Offset,
+                      entry->Length,
+                      entry->CheckSum,
+                      old_length ));
+          entry++;
+        }
+        else
+          continue;
+      }
       else
       {
         FT_TRACE2(( "  %c%c%c%c  %08lx  %08lx  %08lx\n",
diff --git a/src/sfnt/ttload.h b/src/sfnt/ttload.h
index 49a1aee..a6d91c5 100644
--- a/src/sfnt/ttload.h
+++ b/src/sfnt/ttload.h
@@ -5,7 +5,7 @@
 /*    Load the basic TrueType tables, i.e., tables that can be either in   */
 /*    TTF or OTF fonts (specification).                                    */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2005, 2006 by                               */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttmtx.c b/src/sfnt/ttmtx.c
index a8cc63a..58309aa 100644
--- a/src/sfnt/ttmtx.c
+++ b/src/sfnt/ttmtx.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Load the metrics tables common to TTF and OTF fonts (body).          */
 /*                                                                         */
-/*  Copyright 2006-2009, 2011-2013 by                                      */
+/*  Copyright 2006-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -201,7 +201,7 @@
   /*    aadvance :: The advance width or advance height, depending on      */
   /*                the `vertical' flag.                                   */
   /*                                                                       */
-  FT_LOCAL_DEF( FT_Error )
+  FT_LOCAL_DEF( void )
   tt_face_get_metrics( TT_Face     face,
                        FT_Bool     vertical,
                        FT_UInt     gindex,
@@ -274,8 +274,6 @@
       *abearing = 0;
       *aadvance = 0;
     }
-
-    return FT_Err_Ok;
   }
 
 
diff --git a/src/sfnt/ttmtx.h b/src/sfnt/ttmtx.h
index 8b91a11..096ee06 100644
--- a/src/sfnt/ttmtx.h
+++ b/src/sfnt/ttmtx.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Load the metrics tables common to TTF and OTF fonts (specification). */
 /*                                                                         */
-/*  Copyright 2006 by                                                      */
+/*  Copyright 2006-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -40,7 +40,7 @@
                      FT_Bool    vertical );
 
 
-  FT_LOCAL( FT_Error )
+  FT_LOCAL( void )
   tt_face_get_metrics( TT_Face     face,
                        FT_Bool     vertical,
                        FT_UInt     gindex,
diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c
index 99d8005..8d29d1e 100644
--- a/src/sfnt/ttpost.c
+++ b/src/sfnt/ttpost.c
@@ -5,7 +5,7 @@
 /*    Postcript name table processing for TrueType and OpenType fonts      */
 /*    (body).                                                              */
 /*                                                                         */
-/*  Copyright 1996-2003, 2006-2010, 2013, 2014 by                          */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -52,7 +52,7 @@
 
 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
 
-#define MAC_NAME( x )  ( (FT_String*)psnames->macintosh_name( x ) )
+#define MAC_NAME( x )  (FT_String*)psnames->macintosh_name( (FT_UInt)(x) )
 
 
 #else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
@@ -62,7 +62,7 @@
    /* table of Mac names.  Thus, it is possible to build a version of */
    /* FreeType without the Type 1 driver & PSNames module.            */
 
-#define MAC_NAME( x )  ( (FT_String*)tt_post_default_names[x] )
+#define MAC_NAME( x )  (FT_String*)tt_post_default_names[x]
 
   /* the 258 default Mac PS glyph names; see file `tools/glnames.py' */
 
@@ -155,7 +155,7 @@
   static FT_Error
   load_format_20( TT_Face    face,
                   FT_Stream  stream,
-                  FT_Long    post_limit )
+                  FT_ULong   post_limit )
   {
     FT_Memory   memory = stream->memory;
     FT_Error    error;
@@ -163,8 +163,8 @@
     FT_Int      num_glyphs;
     FT_UShort   num_names;
 
-    FT_UShort*  glyph_indices = 0;
-    FT_Char**   name_strings  = 0;
+    FT_UShort*  glyph_indices = NULL;
+    FT_Char**   name_strings  = NULL;
 
 
     if ( FT_READ_USHORT( num_glyphs ) )
@@ -243,14 +243,17 @@
             goto Fail1;
         }
 
-        if ( (FT_Int)len > post_limit                   ||
-             FT_STREAM_POS() > post_limit - (FT_Int)len )
+        if ( len > post_limit                   ||
+             FT_STREAM_POS() > post_limit - len )
         {
+          FT_Int  d = (FT_Int)post_limit - (FT_Int)FT_STREAM_POS();
+
+
           FT_ERROR(( "load_format_20:"
                      " exceeding string length (%d),"
                      " truncating at end of post table (%d byte left)\n",
-                     len, post_limit - FT_STREAM_POS() ));
-          len = FT_MAX( 0, post_limit - FT_STREAM_POS() );
+                     len, d ));
+          len = (FT_UInt)FT_MAX( 0, d );
         }
 
         if ( FT_NEW_ARRAY( name_strings[n], len + 1 ) ||
@@ -307,13 +310,13 @@
   static FT_Error
   load_format_25( TT_Face    face,
                   FT_Stream  stream,
-                  FT_Long    post_limit )
+                  FT_ULong   post_limit )
   {
     FT_Memory  memory = stream->memory;
     FT_Error   error;
 
     FT_Int     num_glyphs;
-    FT_Char*   offset_table = 0;
+    FT_Char*   offset_table = NULL;
 
     FT_UNUSED( post_limit );
 
@@ -377,7 +380,7 @@
     FT_Error   error;
     FT_Fixed   format;
     FT_ULong   post_len;
-    FT_Long    post_limit;
+    FT_ULong   post_limit;
 
 
     /* get a stream for the face's resource */
@@ -547,10 +550,7 @@
       }
 
       if ( idx < (FT_UInt)table->num_glyphs )    /* paranoid checking */
-      {
-        idx    += table->offsets[idx];
-        *PSname = MAC_NAME( idx );
-      }
+        *PSname = MAC_NAME( (FT_Int)idx + table->offsets[idx] );
     }
 
     /* nothing to do for format == 0x00030000L */
diff --git a/src/sfnt/ttpost.h b/src/sfnt/ttpost.h
index 6f06d75..e3eca02 100644
--- a/src/sfnt/ttpost.h
+++ b/src/sfnt/ttpost.h
@@ -5,7 +5,7 @@
 /*    Postcript name table processing for TrueType and OpenType fonts      */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002 by                                           */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index 180d559..143f276 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType and OpenType embedded bitmap support (body).                */
 /*                                                                         */
-/*  Copyright 2005-2009, 2013, 2014 by                                     */
+/*  Copyright 2005-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  Copyright 2013 by Google, Inc.                                         */
@@ -101,10 +101,10 @@
 
         p = face->sbit_table;
 
-        version     = FT_NEXT_ULONG( p );
+        version     = FT_NEXT_LONG( p );
         num_strikes = FT_NEXT_ULONG( p );
 
-        if ( ( version & 0xFFFF0000UL ) != 0x00020000UL )
+        if ( ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00020000UL )
         {
           error = FT_THROW( Unknown_File_Format );
           goto Exit;
@@ -150,12 +150,25 @@
           error = FT_THROW( Unknown_File_Format );
           goto Exit;
         }
-        if ( flags != 0x0001 || num_strikes >= 0x10000UL )
+
+        /* Bit 0 must always be `1'.                            */
+        /* Bit 1 controls the overlay of bitmaps with outlines. */
+        /* All other bits should be zero.                       */
+        if ( !( flags == 1 || flags == 3 ) ||
+             num_strikes >= 0x10000UL      )
         {
           error = FT_THROW( Invalid_File_Format );
           goto Exit;
         }
 
+        /* we currently don't support bit 1; however, it is better to */
+        /* draw at least something...                                 */
+        if ( flags == 3 )
+          FT_TRACE1(( "tt_face_load_sbit_strikes:"
+                      " sbix overlay not supported yet\n"
+                      "                          "
+                      " expect bad rendering results\n" ));
+
         /*
          *  Count the number of strikes available in the table.  We are a bit
          *  paranoid there and don't trust the data.
@@ -260,6 +273,7 @@
         FT_UShort       ppem, resolution;
         TT_HoriHeader  *hori;
         FT_ULong        table_size;
+        FT_Pos          ppem_, upem_; /* to reduce casts */
 
         FT_Error  error;
         FT_Byte*  p;
@@ -292,12 +306,15 @@
         metrics->x_ppem = ppem;
         metrics->y_ppem = ppem;
 
-        metrics->ascender    = ppem * hori->Ascender * 64 / upem;
-        metrics->descender   = ppem * hori->Descender * 64 / upem;
-        metrics->height      = ppem * ( hori->Ascender -
-                                        hori->Descender +
-                                        hori->Line_Gap ) * 64 / upem;
-        metrics->max_advance = ppem * hori->advance_Width_Max * 64 / upem;
+        ppem_ = (FT_Pos)ppem;
+        upem_ = (FT_Pos)upem;
+
+        metrics->ascender    = ppem_ * hori->Ascender * 64 / upem_;
+        metrics->descender   = ppem_ * hori->Descender * 64 / upem_;
+        metrics->height      = ppem_ * ( hori->Ascender -
+                                         hori->Descender +
+                                         hori->Line_Gap ) * 64 / upem_;
+        metrics->max_advance = ppem_ * hori->advance_Width_Max * 64 / upem_;
 
         return error;
       }
@@ -381,9 +398,11 @@
       p                          += 34;
       decoder->bit_depth          = *p;
 
-      if ( decoder->strike_index_array > face->sbit_table_size             ||
-           decoder->strike_index_array + 8 * decoder->strike_index_count >
-             face->sbit_table_size                                         )
+      /* decoder->strike_index_array +                               */
+      /*   8 * decoder->strike_index_count > face->sbit_table_size ? */
+      if ( decoder->strike_index_array > face->sbit_table_size           ||
+           decoder->strike_index_count >
+             ( face->sbit_table_size - decoder->strike_index_array ) / 8 )
         error = FT_THROW( Invalid_File_Format );
     }
 
@@ -405,7 +424,7 @@
     FT_Error    error = FT_Err_Ok;
     FT_UInt     width, height;
     FT_Bitmap*  map = decoder->bitmap;
-    FT_Long     size;
+    FT_ULong    size;
 
 
     if ( !decoder->metrics_loaded )
@@ -417,38 +436,38 @@
     width  = decoder->metrics->width;
     height = decoder->metrics->height;
 
-    map->width = (int)width;
-    map->rows  = (int)height;
+    map->width = width;
+    map->rows  = height;
 
     switch ( decoder->bit_depth )
     {
     case 1:
       map->pixel_mode = FT_PIXEL_MODE_MONO;
-      map->pitch      = ( map->width + 7 ) >> 3;
+      map->pitch      = (int)( ( map->width + 7 ) >> 3 );
       map->num_grays  = 2;
       break;
 
     case 2:
       map->pixel_mode = FT_PIXEL_MODE_GRAY2;
-      map->pitch      = ( map->width + 3 ) >> 2;
+      map->pitch      = (int)( ( map->width + 3 ) >> 2 );
       map->num_grays  = 4;
       break;
 
     case 4:
       map->pixel_mode = FT_PIXEL_MODE_GRAY4;
-      map->pitch      = ( map->width + 1 ) >> 1;
+      map->pitch      = (int)( ( map->width + 1 ) >> 1 );
       map->num_grays  = 16;
       break;
 
     case 8:
       map->pixel_mode = FT_PIXEL_MODE_GRAY;
-      map->pitch      = map->width;
+      map->pitch      = (int)( map->width );
       map->num_grays  = 256;
       break;
 
     case 32:
       map->pixel_mode = FT_PIXEL_MODE_BGRA;
-      map->pitch      = map->width * 4;
+      map->pitch      = (int)( map->width * 4 );
       map->num_grays  = 256;
       break;
 
@@ -457,7 +476,7 @@
       goto Exit;
     }
 
-    size = map->rows * map->pitch;
+    size = map->rows * (FT_ULong)map->pitch;
 
     /* check that there is no empty image */
     if ( size == 0 )
@@ -505,13 +524,20 @@
 
       p += 3;
     }
+    else
+    {
+      /* avoid uninitialized data in case there is no vertical info -- */
+      metrics->vertBearingX = 0;
+      metrics->vertBearingY = 0;
+      metrics->vertAdvance  = 0;
+    }
 
     decoder->metrics_loaded = 1;
     *pp = p;
     return FT_Err_Ok;
 
   Fail:
-    FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table" ));
+    FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table\n" ));
     return FT_THROW( Invalid_Argument );
   }
 
@@ -539,7 +565,8 @@
   {
     FT_Error    error = FT_Err_Ok;
     FT_Byte*    line;
-    FT_Int      bit_height, bit_width, pitch, width, height, line_bits, h;
+    FT_Int      pitch, width, height, line_bits, h;
+    FT_UInt     bit_height, bit_width;
     FT_Bitmap*  bitmap;
 
 
@@ -555,8 +582,8 @@
 
     line_bits = width * decoder->bit_depth;
 
-    if ( x_pos < 0 || x_pos + width > bit_width   ||
-         y_pos < 0 || y_pos + height > bit_height )
+    if ( x_pos < 0 || (FT_UInt)( x_pos + width ) > bit_width   ||
+         y_pos < 0 || (FT_UInt)( y_pos + height ) > bit_height )
     {
       FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:"
                   " invalid bitmap dimensions\n" ));
@@ -677,7 +704,8 @@
   {
     FT_Error    error = FT_Err_Ok;
     FT_Byte*    line;
-    FT_Int      bit_height, bit_width, pitch, width, height, line_bits, h, nbits;
+    FT_Int      pitch, width, height, line_bits, h, nbits;
+    FT_UInt     bit_height, bit_width;
     FT_Bitmap*  bitmap;
     FT_UShort   rval;
 
@@ -694,8 +722,8 @@
 
     line_bits = width * decoder->bit_depth;
 
-    if ( x_pos < 0 || x_pos + width  > bit_width  ||
-         y_pos < 0 || y_pos + height > bit_height )
+    if ( x_pos < 0 || (FT_UInt)( x_pos + width ) > bit_width   ||
+         y_pos < 0 || (FT_UInt)( y_pos + height ) > bit_height )
     {
       FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:"
                   " invalid bitmap dimensions\n" ));
@@ -1148,7 +1176,8 @@
         num_glyphs = FT_NEXT_ULONG( p );
 
         /* overflow check for p + ( num_glyphs + 1 ) * 4 */
-        if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) )
+        if ( p + 4 > p_limit                                         ||
+             num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) )
           goto NoBitmap;
 
         for ( mm = 0; mm < num_glyphs; mm++ )
@@ -1335,6 +1364,7 @@
 
     case FT_MAKE_TAG( 'j', 'p', 'g', ' ' ):
     case FT_MAKE_TAG( 't', 'i', 'f', 'f' ):
+    case FT_MAKE_TAG( 'r', 'g', 'b', 'l' ): /* used on iOS 7.1 */
       error = FT_THROW( Unknown_File_Format );
       break;
 
@@ -1355,9 +1385,9 @@
 
       metrics->horiBearingX = (FT_Short)originOffsetX;
       metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height );
-      metrics->horiAdvance  = (FT_Short)( aadvance *
-                                          face->root.size->metrics.x_ppem /
-                                          face->header.Units_Per_EM );
+      metrics->horiAdvance  = (FT_UShort)( aadvance *
+                                           face->root.size->metrics.x_ppem /
+                                           face->header.Units_Per_EM );
     }
 
     return error;
@@ -1418,7 +1448,7 @@
       FT_Library  library = face->root.glyph->library;
 
 
-      FT_Bitmap_New( &new_map );
+      FT_Bitmap_Init( &new_map );
 
       /* Convert to 8bit grayscale. */
       error = FT_Bitmap_Convert( library, map, &new_map, 1 );
diff --git a/src/sfnt/ttsbit.h b/src/sfnt/ttsbit.h
index 695d0d8..d4e13ae 100644
--- a/src/sfnt/ttsbit.h
+++ b/src/sfnt/ttsbit.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType and OpenType embedded bitmap support (specification).       */
 /*                                                                         */
-/*  Copyright 1996-2008, 2013 by                                           */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 27be966..77b58f2 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    A new `perfect' anti-aliasing renderer (body).                       */
 /*                                                                         */
-/*  Copyright 2000-2003, 2005-2014 by                                      */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -94,6 +94,11 @@
 #ifdef _STANDALONE_
 
 
+  /* The size in bytes of the render pool used by the scan-line converter  */
+  /* to do all of its work.                                                */
+#define FT_RENDER_POOL_SIZE  16384L
+
+
   /* Auxiliary macros for token concatenation. */
 #define FT_ERR_XCAT( x, y )  x ## y
 #define FT_ERR_CAT( x, y )   FT_ERR_XCAT( x, y )
@@ -101,6 +106,21 @@
 #define FT_BEGIN_STMNT  do {
 #define FT_END_STMNT    } while ( 0 )
 
+#define FT_MAX( a, b )  ( (a) > (b) ? (a) : (b) )
+#define FT_ABS( a )     ( (a) < 0 ? -(a) : (a) )
+
+
+  /*
+   *  Approximate sqrt(x*x+y*y) using the `alpha max plus beta min'
+   *  algorithm.  We use alpha = 1, beta = 3/8, giving us results with a
+   *  largest error less than 7% compared to the exact value.
+   */
+#define FT_HYPOT( x, y )                 \
+          ( x = FT_ABS( x ),             \
+            y = FT_ABS( y ),             \
+            x > y ? x + ( 3 * y >> 3 )   \
+                  : y + ( 3 * x >> 3 ) )
+
 
   /* define this to dump debugging information */
 /* #define FT_DEBUG_LEVEL_TRACE */
@@ -405,6 +425,8 @@
 
   typedef struct  gray_TWorker_
   {
+    ft_jmp_buf  jump_buffer;
+
     TCoord  ex, ey;
     TPos    min_ex, max_ex;
     TPos    min_ey, max_ey;
@@ -440,8 +462,6 @@
     int  band_size;
     int  band_shoot;
 
-    ft_jmp_buf  jump_buffer;
-
     void*       buffer;
     long        buffer_size;
 
@@ -464,11 +484,7 @@
 
   typedef struct gray_TRaster_
   {
-    void*         buffer;
-    long          buffer_size;
-    int           band_size;
     void*         memory;
-    gray_PWorker  worker;
 
   } gray_TRaster, *gray_PRaster;
 
@@ -480,7 +496,7 @@
   /*                                                                       */
   static void
   gray_init_cells( RAS_ARG_ void*  buffer,
-                   long            byte_size )
+                            long   byte_size )
   {
     ras.buffer      = buffer;
     ras.buffer_size = byte_size;
@@ -638,8 +654,8 @@
       ras.ey    = ey;
     }
 
-    ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey ||
-                              ex >= ras.count_ex           );
+    ras.invalid = ( (unsigned int)ey >= (unsigned int)ras.count_ey ||
+                                  ex >= ras.count_ex               );
   }
 
 
@@ -1091,37 +1107,10 @@
 
 
         /* dx and dy are x and y components of the P0-P3 chord vector. */
-        dx = arc[3].x - arc[0].x;
-        dy = arc[3].y - arc[0].y;
+        dx = dx_ = arc[3].x - arc[0].x;
+        dy = dy_ = arc[3].y - arc[0].y;
 
-        /* L is an (under)estimate of the Euclidean distance P0-P3.       */
-        /*                                                                */
-        /* If dx >= dy, then r = sqrt(dx^2 + dy^2) can be overestimated   */
-        /* with least maximum error by                                    */
-        /*                                                                */
-        /*   r_upperbound = dx + (sqrt(2) - 1) * dy  ,                    */
-        /*                                                                */
-        /* where sqrt(2) - 1 can be (over)estimated by 107/256, giving an */
-        /* error of no more than 8.4%.                                    */
-        /*                                                                */
-        /* Similarly, some elementary calculus shows that r can be        */
-        /* underestimated with least maximum error by                     */
-        /*                                                                */
-        /*   r_lowerbound = sqrt(2 + sqrt(2)) / 2 * dx                    */
-        /*                  + sqrt(2 - sqrt(2)) / 2 * dy  .               */
-        /*                                                                */
-        /* 236/256 and 97/256 are (under)estimates of the two algebraic   */
-        /* numbers, giving an error of no more than 8.1%.                 */
-
-        dx_ = FT_ABS( dx );
-        dy_ = FT_ABS( dy );
-
-        /* This is the same as                     */
-        /*                                         */
-        /*   L = ( 236 * FT_MAX( dx_, dy_ )        */
-        /*       + 97 * FT_MIN( dx_, dy_ ) ) >> 8; */
-        L = ( dx_ > dy_ ? 236 * dx_ +  97 * dy_
-                        :  97 * dx_ + 236 * dy_ ) >> 8;
+        L = FT_HYPOT( dx_, dy_ );
 
         /* Avoid possible arithmetic overflow below by splitting. */
         if ( L > 32767 )
@@ -1239,7 +1228,7 @@
     /* first of all, compute the scanline offset */
     p = (unsigned char*)map->buffer - y * map->pitch;
     if ( map->pitch >= 0 )
-      p += (unsigned)( ( map->rows - 1 ) * map->pitch );
+      p += ( map->rows - 1 ) * (unsigned int)map->pitch;
 
     for ( ; count > 0; count--, spans++ )
     {
@@ -1542,7 +1531,10 @@
     TPos  delta;
 
 
-    if ( !outline || !func_interface )
+    if ( !outline )
+      return FT_THROW( Invalid_Outline );
+
+    if ( !func_interface )
       return FT_THROW( Invalid_Argument );
 
     shift = func_interface->shift;
@@ -1768,14 +1760,17 @@
 
   } gray_TBand;
 
-    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_DEFINE_OUTLINE_FUNCS(
+    func_interface,
+
+    (FT_Outline_MoveTo_Func) gray_move_to,
+    (FT_Outline_LineTo_Func) gray_line_to,
+    (FT_Outline_ConicTo_Func)gray_conic_to,
+    (FT_Outline_CubicTo_Func)gray_cubic_to,
+    0,
+    0 )
+
 
   static int
   gray_convert_glyph_inner( RAS_ARG )
@@ -1866,13 +1861,13 @@
           ras.ycells = (PCell*)ras.buffer;
           ras.ycount = band->max - band->min;
 
-          cell_start = sizeof ( PCell ) * ras.ycount;
-          cell_mod   = cell_start % sizeof ( TCell );
+          cell_start = (long)sizeof ( PCell ) * ras.ycount;
+          cell_mod   = cell_start % (long)sizeof ( TCell );
           if ( cell_mod > 0 )
-            cell_start += sizeof ( TCell ) - cell_mod;
+            cell_start += (long)sizeof ( TCell ) - cell_mod;
 
           cell_end  = ras.buffer_size;
-          cell_end -= cell_end % sizeof ( TCell );
+          cell_end -= cell_end % (long)sizeof ( TCell );
 
           cells_max = (PCell)( (char*)ras.buffer + cell_end );
           ras.cells = (PCell)( (char*)ras.buffer + cell_start );
@@ -1942,12 +1937,18 @@
   gray_raster_render( gray_PRaster             raster,
                       const FT_Raster_Params*  params )
   {
-    const FT_Outline*  outline    = (const FT_Outline*)params->source;
-    const FT_Bitmap*   target_map = params->target;
-    gray_PWorker       worker;
+    const FT_Outline*  outline     = (const FT_Outline*)params->source;
+    const FT_Bitmap*   target_map  = params->target;
+
+    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 ) );
 
 
-    if ( !raster || !raster->buffer || !raster->buffer_size )
+    if ( !raster )
       return FT_THROW( Invalid_Argument );
 
     if ( !outline )
@@ -1964,8 +1965,6 @@
            outline->contours[outline->n_contours - 1] + 1 )
       return FT_THROW( Invalid_Outline );
 
-    worker = raster->worker;
-
     /* if direct mode is not set, we must have a target bitmap */
     if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
     {
@@ -1990,8 +1989,8 @@
       /* compute clip box from target pixmap */
       ras.clip_box.xMin = 0;
       ras.clip_box.yMin = 0;
-      ras.clip_box.xMax = target_map->width;
-      ras.clip_box.yMax = target_map->rows;
+      ras.clip_box.xMax = (FT_Pos)target_map->width;
+      ras.clip_box.yMax = (FT_Pos)target_map->rows;
     }
     else if ( params->flags & FT_RASTER_FLAG_CLIP )
       ras.clip_box = params->clip_box;
@@ -2003,13 +2002,14 @@
       ras.clip_box.yMax =  32767L;
     }
 
-    gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size );
+    gray_init_cells( RAS_VAR_ buffer, buffer_size );
 
     ras.outline        = *outline;
     ras.num_cells      = 0;
     ras.invalid        = 1;
-    ras.band_size      = raster->band_size;
+    ras.band_size      = band_size;
     ras.num_gray_spans = 0;
+    ras.span_y         = 0;
 
     if ( params->flags & FT_RASTER_FLAG_DIRECT )
     {
@@ -2093,46 +2093,36 @@
                      char*      pool_base,
                      long       pool_size )
   {
-    gray_PRaster  rast = (gray_PRaster)raster;
-
-
-    if ( raster )
-    {
-      if ( pool_base && pool_size >= (long)sizeof ( gray_TWorker ) + 2048 )
-      {
-        gray_PWorker  worker = (gray_PWorker)pool_base;
-
-
-        rast->worker      = worker;
-        rast->buffer      = pool_base +
-                              ( ( sizeof ( gray_TWorker ) +
-                                  sizeof ( TCell ) - 1 )  &
-                                ~( sizeof ( TCell ) - 1 ) );
-        rast->buffer_size = (long)( ( pool_base + pool_size ) -
-                                    (char*)rast->buffer ) &
-                                      ~( sizeof ( TCell ) - 1 );
-        rast->band_size   = (int)( rast->buffer_size /
-                                     ( sizeof ( TCell ) * 8 ) );
-      }
-      else
-      {
-        rast->buffer      = NULL;
-        rast->buffer_size = 0;
-        rast->worker      = NULL;
-      }
-    }
+    FT_UNUSED( raster );
+    FT_UNUSED( pool_base );
+    FT_UNUSED( pool_size );
   }
 
 
-  FT_DEFINE_RASTER_FUNCS(ft_grays_raster,
+  static int
+  gray_raster_set_mode( FT_Raster      raster,
+                        unsigned long  mode,
+                        void*          args )
+  {
+    FT_UNUSED( raster );
+    FT_UNUSED( mode );
+    FT_UNUSED( args );
+
+
+    return 0; /* nothing to do */
+  }
+
+
+  FT_DEFINE_RASTER_FUNCS(
+    ft_grays_raster,
+
     FT_GLYPH_FORMAT_OUTLINE,
 
     (FT_Raster_New_Func)     gray_raster_new,
     (FT_Raster_Reset_Func)   gray_raster_reset,
-    (FT_Raster_Set_Mode_Func)0,
+    (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_Done_Func)    gray_raster_done )
 
 
 /* END */
diff --git a/src/smooth/ftgrays.h b/src/smooth/ftgrays.h
index f20f55f..1b57603 100644
--- a/src/smooth/ftgrays.h
+++ b/src/smooth/ftgrays.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType smooth renderer declaration                                 */
 /*                                                                         */
-/*  Copyright 1996-2001 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/smooth/ftsmerrs.h b/src/smooth/ftsmerrs.h
index 413d2f1..cc38aa1 100644
--- a/src/smooth/ftsmerrs.h
+++ b/src/smooth/ftsmerrs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    smooth renderer error codes (specification only).                    */
 /*                                                                         */
-/*  Copyright 2001, 2012 by                                                */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c
index 89088cd..3620550 100644
--- a/src/smooth/ftsmooth.c
+++ b/src/smooth/ftsmooth.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Anti-aliasing renderer interface (body).                             */
 /*                                                                         */
-/*  Copyright 2000-2006, 2009-2013 by                                      */
+/*  Copyright 2000-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -103,25 +103,24 @@
                             FT_Render_Mode    required_mode )
   {
     FT_Error     error;
-    FT_Outline*  outline = NULL;
+    FT_Outline*  outline = &slot->outline;
+    FT_Bitmap*   bitmap  = &slot->bitmap;
+    FT_Memory    memory  = render->root.memory;
     FT_BBox      cbox;
+    FT_Pos       x_shift = 0;
+    FT_Pos       y_shift = 0;
+    FT_Pos       x_left, y_top;
     FT_Pos       width, height, pitch;
 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
     FT_Pos       height_org, width_org;
 #endif
-    FT_Bitmap*   bitmap  = &slot->bitmap;
-    FT_Memory    memory  = render->root.memory;
     FT_Int       hmul    = mode == FT_RENDER_MODE_LCD;
     FT_Int       vmul    = mode == FT_RENDER_MODE_LCD_V;
-    FT_Pos       x_shift = 0;
-    FT_Pos       y_shift = 0;
-    FT_Pos       x_left, y_top;
 
     FT_Raster_Params  params;
 
-    FT_Bool  have_translated_origin = FALSE;
-    FT_Bool  have_outline_shifted   = FALSE;
-    FT_Bool  have_buffer            = FALSE;
+    FT_Bool  have_outline_shifted = FALSE;
+    FT_Bool  have_buffer          = FALSE;
 
 
     /* check glyph image format */
@@ -138,73 +137,45 @@
       goto Exit;
     }
 
-    outline = &slot->outline;
-
-    /* translate the outline to the new origin if needed */
     if ( origin )
     {
-      FT_Outline_Translate( outline, origin->x, origin->y );
-      have_translated_origin = TRUE;
+      x_shift = origin->x;
+      y_shift = origin->y;
     }
 
     /* compute the control box, and grid fit it */
+    /* taking into account the origin shift     */
     FT_Outline_Get_CBox( outline, &cbox );
 
-    cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
-    cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
-    cbox.xMax = FT_PIX_CEIL( cbox.xMax );
-    cbox.yMax = FT_PIX_CEIL( cbox.yMax );
+    cbox.xMin = FT_PIX_FLOOR( cbox.xMin + x_shift );
+    cbox.yMin = FT_PIX_FLOOR( cbox.yMin + y_shift );
+    cbox.xMax = FT_PIX_CEIL( cbox.xMax + x_shift );
+    cbox.yMax = FT_PIX_CEIL( cbox.yMax + y_shift );
 
-    if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin )
-    {
-      FT_ERROR(( "ft_smooth_render_generic: glyph too large:"
-                 " xMin = %d, xMax = %d\n",
-                 cbox.xMin >> 6, cbox.xMax >> 6 ));
-      error = FT_THROW( Raster_Overflow );
-      goto Exit;
-    }
-    else
-      width = ( cbox.xMax - cbox.xMin ) >> 6;
+    x_shift -= cbox.xMin;
+    y_shift -= cbox.yMin;
 
-    if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin )
-    {
-      FT_ERROR(( "ft_smooth_render_generic: glyph too large:"
-                 " yMin = %d, yMax = %d\n",
-                 cbox.yMin >> 6, cbox.yMax >> 6 ));
-      error = FT_THROW( Raster_Overflow );
-      goto Exit;
-    }
-    else
-      height = ( cbox.yMax - cbox.yMin ) >> 6;
+    x_left  = cbox.xMin >> 6;
+    y_top   = cbox.yMax >> 6;
+
+    width  = (FT_ULong)( cbox.xMax - cbox.xMin ) >> 6;
+    height = (FT_ULong)( cbox.yMax - cbox.yMin ) >> 6;
 
 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
     width_org  = width;
     height_org = height;
 #endif
 
-    /* release old bitmap buffer */
-    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
-    {
-      FT_FREE( bitmap->buffer );
-      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
-    }
-
-    /* allocate new one */
     pitch = width;
     if ( hmul )
     {
-      width = width * 3;
-      pitch = FT_PAD_CEIL( width, 4 );
+      width *= 3;
+      pitch  = FT_PAD_CEIL( width, 4 );
     }
 
     if ( vmul )
       height *= 3;
 
-    x_shift = (FT_Int) cbox.xMin;
-    y_shift = (FT_Int) cbox.yMin;
-    x_left  = (FT_Int)( cbox.xMin >> 6 );
-    y_top   = (FT_Int)( cbox.yMax >> 6 );
-
 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
 
     if ( slot->library->lcd_filter_func )
@@ -214,23 +185,32 @@
 
       if ( hmul )
       {
-        x_shift -= 64 * ( extra >> 1 );
+        x_shift += 64 * ( extra >> 1 );
+        x_left  -= extra >> 1;
         width   += 3 * extra;
         pitch    = FT_PAD_CEIL( width, 4 );
-        x_left  -= extra >> 1;
       }
 
       if ( vmul )
       {
-        y_shift -= 64 * ( extra >> 1 );
-        height  += 3 * extra;
+        y_shift += 64 * ( extra >> 1 );
         y_top   += extra >> 1;
+        height  += 3 * extra;
       }
     }
 
 #endif
 
-#if FT_UINT_MAX > 0xFFFFU
+    /*
+     * XXX: on 16bit system, we return an error for huge bitmap
+     * to prevent an overflow.
+     */
+    if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX ||
+         x_left < FT_INT_MIN || y_top < FT_INT_MIN )
+    {
+      error = FT_THROW( Invalid_Pixel_Size );
+      goto Exit;
+    }
 
     /* Required check is (pitch * height < FT_ULONG_MAX),        */
     /* but we care realistic cases only.  Always pitch <= width. */
@@ -242,25 +222,38 @@
       goto Exit;
     }
 
-#endif
+    /* release old bitmap buffer */
+    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
+    {
+      FT_FREE( bitmap->buffer );
+      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
+    }
 
-    bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
-    bitmap->num_grays  = 256;
-    bitmap->width      = width;
-    bitmap->rows       = height;
-    bitmap->pitch      = pitch;
-
-    /* translate outline to render it into the bitmap */
-    FT_Outline_Translate( outline, -x_shift, -y_shift );
-    have_outline_shifted = TRUE;
-
-    if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) )
+    /* allocate new one */
+    if ( FT_ALLOC( bitmap->buffer, (FT_ULong)( pitch * height ) ) )
       goto Exit;
     else
       have_buffer = TRUE;
 
     slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
 
+    slot->format      = FT_GLYPH_FORMAT_BITMAP;
+    slot->bitmap_left = (FT_Int)x_left;
+    slot->bitmap_top  = (FT_Int)y_top;
+
+    bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
+    bitmap->num_grays  = 256;
+    bitmap->width      = (unsigned int)width;
+    bitmap->rows       = (unsigned int)height;
+    bitmap->pitch      = pitch;
+
+    /* translate outline to render it into the bitmap */
+    if ( x_shift || y_shift )
+    {
+      FT_Outline_Translate( outline, x_shift, y_shift );
+      have_outline_shifted = TRUE;
+    }
+
     /* set up parameters */
     params.target = bitmap;
     params.source = outline;
@@ -366,20 +359,6 @@
 
 #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
 
-    /*
-     * XXX: on 16bit system, we return an error for huge bitmap
-     * to prevent an overflow.
-     */
-    if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX )
-    {
-      error = FT_THROW( Invalid_Pixel_Size );
-      goto Exit;
-    }
-
-    slot->format      = FT_GLYPH_FORMAT_BITMAP;
-    slot->bitmap_left = (FT_Int)x_left;
-    slot->bitmap_top  = (FT_Int)y_top;
-
     /* everything is fine; don't deallocate buffer */
     have_buffer = FALSE;
 
@@ -387,9 +366,7 @@
 
   Exit:
     if ( have_outline_shifted )
-      FT_Outline_Translate( outline, x_shift, y_shift );
-    if ( have_translated_origin )
-      FT_Outline_Translate( outline, -origin->x, -origin->y );
+      FT_Outline_Translate( outline, -x_shift, -y_shift );
     if ( have_buffer )
     {
       FT_FREE( bitmap->buffer );
diff --git a/src/smooth/ftsmooth.h b/src/smooth/ftsmooth.h
index 3708790..765018c 100644
--- a/src/smooth/ftsmooth.h
+++ b/src/smooth/ftsmooth.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Anti-aliasing renderer interface (specification).                    */
 /*                                                                         */
-/*  Copyright 1996-2001 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/smooth/ftspic.c b/src/smooth/ftspic.c
index 67a2b83..8e6ed57 100644
--- a/src/smooth/ftspic.c
+++ b/src/smooth/ftspic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for smooth module.   */
 /*                                                                         */
-/*  Copyright 2009, 2010, 2012, 2013 by                                    */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/smooth/ftspic.h b/src/smooth/ftspic.h
index 334b51c..99b9f0e 100644
--- a/src/smooth/ftspic.h
+++ b/src/smooth/ftspic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for smooth module.   */
 /*                                                                         */
-/*  Copyright 2009 by                                                      */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/smooth/smooth.c b/src/smooth/smooth.c
index a8ac51f..4ca4344 100644
--- a/src/smooth/smooth.c
+++ b/src/smooth/smooth.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType anti-aliasing rasterer module component (body only).        */
 /*                                                                         */
-/*  Copyright 1996-2001 by                                                 */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/truetype.c b/src/truetype/truetype.c
index 576912b..f929437 100644
--- a/src/truetype/truetype.c
+++ b/src/truetype/truetype.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType TrueType driver component (body only).                      */
 /*                                                                         */
-/*  Copyright 1996-2001, 2004, 2006, 2012 by                               */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c
index 36d23a2..08b30c9 100644
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType font driver implementation (body).                          */
 /*                                                                         */
-/*  Copyright 1996-2013 by                                                 */
+/*  Copyright 1996-2015 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 @@
 #include FT_INTERNAL_DEBUG_H
 #include FT_INTERNAL_STREAM_H
 #include FT_INTERNAL_SFNT_H
-#include FT_SERVICE_XFREE86_NAME_H
+#include FT_SERVICE_FONT_FORMAT_H
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 #include FT_MULTIPLE_MASTERS_H
@@ -134,11 +134,6 @@
   /*************************************************************************/
 
 
-#undef  PAIR_TAG
-#define PAIR_TAG( left, right )  ( ( (FT_ULong)left << 16 ) | \
-                                     (FT_ULong)right        )
-
-
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -191,9 +186,6 @@
   }
 
 
-#undef PAIR_TAG
-
-
   static FT_Error
   tt_get_advances( FT_Face    ttface,
                    FT_UInt    start,
@@ -267,7 +259,7 @@
       /* use the scaled metrics, even when tt_size_reset fails */
       FT_Select_Metrics( size->face, strike_index );
 
-      tt_size_reset( ttsize );
+      tt_size_reset( ttsize ); /* ignore return value */
     }
     else
     {
@@ -370,7 +362,7 @@
       return FT_THROW( Invalid_Size_Handle );
 
     if ( !face )
-      return FT_THROW( Invalid_Argument );
+      return FT_THROW( Invalid_Face_Handle );
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
     if ( glyph_index >= (FT_UInt)face->num_glyphs &&
@@ -456,7 +448,7 @@
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
   FT_DEFINE_SERVICEDESCREC5(
     tt_services,
-    FT_SERVICE_ID_XF86_NAME,       FT_XF86_FORMAT_TRUETYPE,
+    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,
@@ -464,7 +456,7 @@
 #else
   FT_DEFINE_SERVICEDESCREC4(
     tt_services,
-    FT_SERVICE_ID_XF86_NAME,       FT_XF86_FORMAT_TRUETYPE,
+    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,
     FT_SERVICE_ID_PROPERTIES,      &TT_SERVICE_PROPERTIES_GET )
@@ -481,7 +473,7 @@
     SFNT_Service         sfnt;
 
 
-    /* TT_SERVICES_GET derefers `library' in PIC mode */
+    /* TT_SERVICES_GET dereferences `library' in PIC mode */
 #ifdef FT_CONFIG_OPTION_PIC
     if ( !driver )
       return NULL;
diff --git a/src/truetype/ttdriver.h b/src/truetype/ttdriver.h
index aae00f2..6cacd60 100644
--- a/src/truetype/ttdriver.h
+++ b/src/truetype/ttdriver.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level TrueType driver interface (specification).                */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002 by                                           */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/tterrors.h b/src/truetype/tterrors.h
index 78d138f..ba32cf7 100644
--- a/src/truetype/tterrors.h
+++ b/src/truetype/tterrors.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType error codes (specification only).                           */
 /*                                                                         */
-/*  Copyright 2001, 2012 by                                                */
+/*  Copyright 2001-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index ff2b339..e1acd69 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType Glyph Loader (body).                                        */
 /*                                                                         */
-/*  Copyright 1996-2014                                                    */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -100,13 +100,15 @@
     else if ( face->os2.version != 0xFFFFU )
     {
       *tsb = (FT_Short)( face->os2.sTypoAscender - yMax );
-      *ah  = face->os2.sTypoAscender - face->os2.sTypoDescender;
+      *ah  = (FT_UShort)FT_ABS( face->os2.sTypoAscender -
+                                face->os2.sTypoDescender );
     }
 
     else
     {
       *tsb = (FT_Short)( face->horizontal.Ascender - yMax );
-      *ah  = face->horizontal.Ascender - face->horizontal.Descender;
+      *ah  = (FT_UShort)FT_ABS( face->horizontal.Ascender -
+                                face->horizontal.Descender );
     }
 
     FT_TRACE5(( "  advance height (font units): %d\n", *ah ));
@@ -151,14 +153,16 @@
     loader->vadvance     = advance_height;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
+    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
+         loader->exec                                             )
     {
-      if ( loader->exec )
-        loader->exec->sph_tweak_flags = 0;
+      loader->exec->sph_tweak_flags = 0;
 
-      /* this may not be the right place for this, but it works */
-      if ( loader->exec && loader->exec->ignore_x_mode )
-        sph_set_tweaks( loader, glyph_index );
+      /* This may not be the right place for this, but it works...  */
+      /* Note that we have to unconditionally load the tweaks since */
+      /* it is possible that glyphs individually switch ClearType's */
+      /* backwards compatibility mode on and off.                   */
+      sph_set_tweaks( loader, glyph_index );
     }
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
@@ -407,7 +411,7 @@
 
     /* reading the bytecode instructions */
     load->glyph->control_len  = 0;
-    load->glyph->control_data = 0;
+    load->glyph->control_data = NULL;
 
     if ( p + 2 > limit )
       goto Invalid_Outline;
@@ -555,8 +559,8 @@
       *flag  = (FT_Byte)( f & FT_CURVE_TAG_ON );
     }
 
-    outline->n_points   = (FT_UShort)n_points;
-    outline->n_contours = (FT_Short) n_contours;
+    outline->n_points   = (FT_Short)n_points;
+    outline->n_contours = (FT_Short)n_contours;
 
     load->cursor = p;
 
@@ -619,15 +623,31 @@
         goto Invalid_Composite;
 
       /* read arguments */
-      if ( subglyph->flags & ARGS_ARE_WORDS )
+      if ( subglyph->flags & ARGS_ARE_XY_VALUES )
       {
-        subglyph->arg1 = FT_NEXT_SHORT( p );
-        subglyph->arg2 = FT_NEXT_SHORT( p );
+        if ( subglyph->flags & ARGS_ARE_WORDS )
+        {
+          subglyph->arg1 = FT_NEXT_SHORT( p );
+          subglyph->arg2 = FT_NEXT_SHORT( p );
+        }
+        else
+        {
+          subglyph->arg1 = FT_NEXT_CHAR( p );
+          subglyph->arg2 = FT_NEXT_CHAR( p );
+        }
       }
       else
       {
-        subglyph->arg1 = FT_NEXT_CHAR( p );
-        subglyph->arg2 = FT_NEXT_CHAR( p );
+        if ( subglyph->flags & ARGS_ARE_WORDS )
+        {
+          subglyph->arg1 = (FT_Int)FT_NEXT_USHORT( p );
+          subglyph->arg2 = (FT_Int)FT_NEXT_USHORT( p );
+        }
+        else
+        {
+          subglyph->arg1 = (FT_Int)FT_NEXT_BYTE( p );
+          subglyph->arg2 = (FT_Int)FT_NEXT_BYTE( p );
+        }
       }
 
       /* read transform */
@@ -707,9 +727,10 @@
                    FT_UInt       start_point,
                    FT_UInt       start_contour )
   {
-    zone->n_points    = (FT_UShort)( load->outline.n_points - start_point );
-    zone->n_contours  = (FT_Short) ( load->outline.n_contours -
-                                       start_contour );
+    zone->n_points    = (FT_UShort)load->outline.n_points -
+                          (FT_UShort)start_point;
+    zone->n_contours  = load->outline.n_contours -
+                          (FT_Short)start_contour;
     zone->org         = load->extra_points + start_point;
     zone->cur         = load->outline.points + start_point;
     zone->orus        = load->extra_points2 + start_point;
@@ -740,7 +761,7 @@
     TT_GlyphZone  zone = &loader->zone;
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
-    FT_UInt       n_ins;
+    FT_Long       n_ins;
 #else
     FT_UNUSED( is_composite );
 #endif
@@ -753,7 +774,7 @@
       FT_TRACE1(( " (0x%lx byte) is truncated\n",
                  loader->glyph->control_len ));
     }
-    n_ins = (FT_UInt)( loader->glyph->control_len );
+    n_ins = loader->glyph->control_len;
 
     /* save original point position in org */
     if ( n_ins > 0 )
@@ -794,25 +815,19 @@
 
     if ( n_ins > 0 )
     {
-      FT_Bool   debug;
       FT_Error  error;
 
       FT_GlyphLoader  gloader         = loader->gloader;
       FT_Outline      current_outline = gloader->current.outline;
 
 
-      error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
-                                loader->exec->glyphIns, n_ins );
-      if ( error )
-        return error;
+      TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
+                        loader->exec->glyphIns, n_ins );
 
       loader->exec->is_composite = is_composite;
       loader->exec->pts          = *zone;
 
-      debug = FT_BOOL( !( loader->load_flags & FT_LOAD_NO_SCALE ) &&
-                       ((TT_Size)loader->size)->debug             );
-
-      error = TT_Run_Context( loader->exec, debug );
+      error = TT_Run_Context( loader->exec );
       if ( error && loader->exec->pedantic_hinting )
         return error;
 
@@ -885,25 +900,12 @@
     if ( ((TT_Face)loader->face)->doblend )
     {
       /* Deltas apply to the unscaled data. */
-      FT_Vector*  deltas;
-      FT_Memory   memory = loader->face->memory;
-      FT_Int      i;
-
-
-      error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face),
-                                        loader->glyph_index,
-                                        &deltas,
-                                        n_points );
+      error = TT_Vary_Apply_Glyph_Deltas( (TT_Face)(loader->face),
+                                           loader->glyph_index,
+                                           outline,
+                                           (FT_UInt)n_points );
       if ( error )
         return error;
-
-      for ( i = 0; i < n_points; ++i )
-      {
-        outline->points[i].x += deltas[i].x;
-        outline->points[i].y += deltas[i].y;
-      }
-
-      FT_FREE( deltas );
     }
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@@ -922,9 +924,9 @@
       TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
 
       FT_String*  family         = face->root.family_name;
-      FT_Int      ppem           = loader->size->metrics.x_ppem;
+      FT_UInt     ppem           = loader->size->metrics.x_ppem;
       FT_String*  style          = face->root.style_name;
-      FT_Int      x_scale_factor = 1000;
+      FT_UInt     x_scale_factor = 1000;
 #endif
 
       FT_Vector*  vec   = outline->points;
@@ -952,7 +954,7 @@
              x_scale_factor != 1000                         )
         {
           x_scale = FT_MulDiv( ((TT_Size)loader->size)->metrics.x_scale,
-                               x_scale_factor, 1000 );
+                               (FT_Long)x_scale_factor, 1000 );
           y_scale = ((TT_Size)loader->size)->metrics.y_scale;
 
           /* compensate for any scaling by de/emboldening; */
@@ -1023,7 +1025,7 @@
   {
     FT_GlyphLoader  gloader    = loader->gloader;
     FT_Vector*      base_vec   = gloader->base.outline.points;
-    FT_UInt         num_points = gloader->base.outline.n_points;
+    FT_UInt         num_points = (FT_UInt)gloader->base.outline.n_points;
     FT_Bool         have_scale;
     FT_Pos          x, y;
 
@@ -1045,8 +1047,8 @@
     /* get offset */
     if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) )
     {
-      FT_UInt     k = subglyph->arg1;
-      FT_UInt     l = subglyph->arg2;
+      FT_UInt     k = (FT_UInt)subglyph->arg1;
+      FT_UInt     l = (FT_UInt)subglyph->arg2;
       FT_Vector*  p1;
       FT_Vector*  p2;
 
@@ -1352,11 +1354,14 @@
 #define TT_LOADER_SET_PP( loader )                                          \
           do                                                                \
           {                                                                 \
-            FT_Bool  subpixel_  = loader->exec ? loader->exec->subpixel     \
-                                               : 0;                         \
-            FT_Bool  grayscale_ = loader->exec ? loader->exec->grayscale    \
-                                               : 0;                         \
-            FT_Bool  use_aw_2_  = (FT_Bool)( subpixel_ && grayscale_ );     \
+            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; \
@@ -1411,10 +1416,6 @@
     FT_GlyphLoader  gloader      = loader->gloader;
     FT_Bool         opened_frame = 0;
 
-#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-    FT_Vector*      deltas       = NULL;
-#endif
-
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
     FT_StreamRec    inc_stream;
     FT_Data         glyph_data;
@@ -1431,12 +1432,14 @@
       goto Exit;
     }
 
+#ifndef FT_CONFIG_OPTION_INCREMENTAL
     /* check glyph index */
     if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
     {
       error = FT_THROW( Invalid_Glyph_Index );
       goto Exit;
     }
+#endif
 
     loader->glyph_index = glyph_index;
 
@@ -1474,7 +1477,8 @@
 
       FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) );
       FT_Stream_OpenMemory( &inc_stream,
-                            glyph_data.pointer, glyph_data.length );
+                            glyph_data.pointer,
+                            (FT_ULong)glyph_data.length );
 
       loader->stream = &inc_stream;
     }
@@ -1502,7 +1506,7 @@
 
       error = face->access_glyph_frame( loader, glyph_index,
                                         loader->glyf_offset + offset,
-                                        loader->byte_len );
+                                        (FT_UInt)loader->byte_len );
       if ( error )
         goto Exit;
 
@@ -1550,26 +1554,47 @@
 
       if ( ((TT_Face)(loader->face))->doblend )
       {
+        /* a small outline structure with four elements for */
+        /* communication with `TT_Vary_Apply_Glyph_Deltas'  */
+        FT_Vector   points[4];
+        char        tags[4]     = { 1, 1, 1, 1 };
+        short       contours[4] = { 0, 1, 2, 3 };
+        FT_Outline  outline;
+
+
+        points[0].x = loader->pp1.x;
+        points[0].y = loader->pp1.y;
+        points[1].x = loader->pp2.x;
+        points[1].y = loader->pp2.y;
+
+        points[2].x = loader->pp3.x;
+        points[2].y = loader->pp3.y;
+        points[3].x = loader->pp4.x;
+        points[3].y = loader->pp4.y;
+
+        outline.n_points   = 4;
+        outline.n_contours = 4;
+        outline.points     = points;
+        outline.tags       = tags;
+        outline.contours   = contours;
+
         /* this must be done before scaling */
-        FT_Memory  memory = loader->face->memory;
-
-
-        error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face),
-                                          glyph_index, &deltas, 4 );
+        error = TT_Vary_Apply_Glyph_Deltas( (TT_Face)(loader->face),
+                                             glyph_index,
+                                             &outline,
+                                             outline.n_points );
         if ( error )
           goto Exit;
 
-        loader->pp1.x += deltas[0].x;
-        loader->pp1.y += deltas[0].y;
-        loader->pp2.x += deltas[1].x;
-        loader->pp2.y += deltas[1].y;
+        loader->pp1.x = points[0].x;
+        loader->pp1.y = points[0].y;
+        loader->pp2.x = points[1].x;
+        loader->pp2.y = points[1].y;
 
-        loader->pp3.x += deltas[2].x;
-        loader->pp3.y += deltas[2].y;
-        loader->pp4.x += deltas[3].x;
-        loader->pp4.y += deltas[3].y;
-
-        FT_FREE( deltas );
+        loader->pp3.x = points[2].x;
+        loader->pp3.y = points[2].y;
+        loader->pp4.x = points[3].x;
+        loader->pp4.y = points[3].y;
       }
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@@ -1635,8 +1660,8 @@
       FT_ULong  ins_pos;  /* position of composite instructions, if any */
 
 
-      start_point   = gloader->base.outline.n_points;
-      start_contour = gloader->base.outline.n_contours;
+      start_point   = (FT_UInt)gloader->base.outline.n_points;
+      start_contour = (FT_UInt)gloader->base.outline.n_contours;
 
       /* for each subglyph, read composite header */
       error = face->read_composite_glyph( loader );
@@ -1654,47 +1679,106 @@
 
       if ( face->doblend )
       {
-        FT_Int       i, limit;
+        FT_UInt      i, limit;
         FT_SubGlyph  subglyph;
-        FT_Memory    memory = face->root.memory;
+
+        FT_Outline  outline;
+        FT_Vector*  points   = NULL;
+        char*       tags     = NULL;
+        short*      contours = NULL;
+
+        FT_Memory  memory = face->root.memory;
 
 
-        /* this provides additional offsets */
-        /* for each component's translation */
+        limit = gloader->current.num_subglyphs;
 
-        if ( ( error = TT_Vary_Get_Glyph_Deltas(
-                         face,
-                         glyph_index,
-                         &deltas,
-                         gloader->current.num_subglyphs + 4 ) ) != 0 )
-          goto Exit;
+        /* construct an outline structure for              */
+        /* communication with `TT_Vary_Apply_Glyph_Deltas' */
+        outline.n_points   = gloader->current.num_subglyphs + 4;
+        outline.n_contours = outline.n_points;
+
+        if ( FT_NEW_ARRAY( points, outline.n_points )   ||
+             FT_NEW_ARRAY( tags, outline.n_points )     ||
+             FT_NEW_ARRAY( contours, outline.n_points ) )
+          goto Exit1;
 
         subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs;
-        limit    = gloader->current.num_subglyphs;
 
-        for ( i = 0; i < limit; ++i, ++subglyph )
+        for ( i = 0; i < limit; i++, subglyph++ )
         {
-          if ( subglyph->flags & ARGS_ARE_XY_VALUES )
-          {
-            /* XXX: overflow check for subglyph->{arg1,arg2}.   */
-            /* deltas[i].{x,y} must be within signed 16-bit,    */
-            /* but the restriction of summed delta is not clear */
-            subglyph->arg1 += (FT_Int16)deltas[i].x;
-            subglyph->arg2 += (FT_Int16)deltas[i].y;
-          }
+          /* applying deltas for anchor points doesn't make sense, */
+          /* but we don't have to specially check this since       */
+          /* unused delta values are zero anyways                  */
+          points[i].x = subglyph->arg1;
+          points[i].y = subglyph->arg2;
+          tags[i]     = 1;
+          contours[i] = i;
         }
 
-        loader->pp1.x += deltas[i + 0].x;
-        loader->pp1.y += deltas[i + 0].y;
-        loader->pp2.x += deltas[i + 1].x;
-        loader->pp2.y += deltas[i + 1].y;
+        points[i].x = loader->pp1.x;
+        points[i].y = loader->pp1.y;
+        tags[i]     = 1;
+        contours[i] = i;
 
-        loader->pp3.x += deltas[i + 2].x;
-        loader->pp3.y += deltas[i + 2].y;
-        loader->pp4.x += deltas[i + 3].x;
-        loader->pp4.y += deltas[i + 3].y;
+        i++;
+        points[i].x = loader->pp2.x;
+        points[i].y = loader->pp2.y;
+        tags[i]     = 1;
+        contours[i] = i;
 
-        FT_FREE( deltas );
+        i++;
+        points[i].x = loader->pp3.x;
+        points[i].y = loader->pp3.y;
+        tags[i]     = 1;
+        contours[i] = i;
+
+        i++;
+        points[i].x = loader->pp4.x;
+        points[i].y = loader->pp4.y;
+        tags[i]     = 1;
+        contours[i] = i;
+
+        outline.points   = points;
+        outline.tags     = tags;
+        outline.contours = contours;
+
+        /* this call provides additional offsets */
+        /* for each component's translation      */
+        if ( ( error = TT_Vary_Apply_Glyph_Deltas(
+                         face,
+                         glyph_index,
+                         &outline,
+                         outline.n_points ) ) != 0 )
+          goto Exit1;
+
+        subglyph = gloader->current.subglyphs + gloader->base.num_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;
+        }
+
+        loader->pp1.x = points[i + 0].x;
+        loader->pp1.y = points[i + 0].y;
+        loader->pp2.x = points[i + 1].x;
+        loader->pp2.y = points[i + 1].y;
+
+        loader->pp3.x = points[i + 2].x;
+        loader->pp3.y = points[i + 2].y;
+        loader->pp4.x = points[i + 3].x;
+        loader->pp4.y = points[i + 3].y;
+
+      Exit1:
+        FT_FREE( outline.points );
+        FT_FREE( outline.tags );
+        FT_FREE( outline.contours );
+
+        if ( error )
+          goto Exit;
       }
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@@ -1730,7 +1814,7 @@
 
       {
         FT_UInt      n, num_base_points;
-        FT_SubGlyph  subglyph       = 0;
+        FT_SubGlyph  subglyph       = NULL;
 
         FT_UInt      num_points     = start_point;
         FT_UInt      num_subglyphs  = gloader->current.num_subglyphs;
@@ -1759,10 +1843,12 @@
           pp[2] = loader->pp3;
           pp[3] = loader->pp4;
 
-          num_base_points = gloader->base.outline.n_points;
+          num_base_points = (FT_UInt)gloader->base.outline.n_points;
 
-          error = load_truetype_glyph( loader, subglyph->index,
-                                       recurse_count + 1, FALSE );
+          error = load_truetype_glyph( loader,
+                                       (FT_UInt)subglyph->index,
+                                       recurse_count + 1,
+                                       FALSE );
           if ( error )
             goto Exit;
 
@@ -1778,7 +1864,7 @@
             loader->pp4 = pp[3];
           }
 
-          num_points = gloader->base.outline.n_points;
+          num_points = (FT_UInt)gloader->base.outline.n_points;
 
           if ( num_points == num_base_points )
             continue;
@@ -1789,8 +1875,12 @@
           /* (1): exists from the beginning                               */
           /* (2): components that have been loaded so far                 */
           /* (3): the newly loaded component                              */
-          TT_Process_Composite_Component( loader, subglyph, start_point,
-                                          num_base_points );
+          error = TT_Process_Composite_Component( loader,
+                                                  subglyph,
+                                                  start_point,
+                                                  num_base_points );
+          if ( error )
+            goto Exit;
         }
 
         loader->stream   = old_stream;
@@ -1799,16 +1889,17 @@
         /* process the glyph */
         loader->ins_pos = ins_pos;
         if ( IS_HINTED( loader->load_flags ) &&
-
 #ifdef TT_USE_BYTECODE_INTERPRETER
-
              subglyph->flags & WE_HAVE_INSTR &&
-
 #endif
-
              num_points > start_point )
-          TT_Process_Composite_Glyph( loader, start_point, start_contour );
-
+        {
+          error = TT_Process_Composite_Glyph( loader,
+                                              start_point,
+                                              start_contour );
+          if ( error )
+            goto Exit;
+        }
       }
     }
     else
@@ -2036,7 +2127,7 @@
     error = sfnt->load_sbit_image( face,
                                    size->strike_index,
                                    glyph_index,
-                                   (FT_Int)load_flags,
+                                   (FT_UInt)load_flags,
                                    stream,
                                    &glyph->bitmap,
                                    &metrics );
@@ -2083,6 +2174,8 @@
                   FT_Int32      load_flags,
                   FT_Bool       glyf_table_only )
   {
+    FT_Error  error;
+
     TT_Face    face;
     FT_Stream  stream;
 #ifdef TT_USE_BYTECODE_INTERPRETER
@@ -2106,14 +2199,16 @@
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
       TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
 
-      FT_Bool  subpixel = FALSE;
+      FT_Bool  subpixel_hinting = FALSE;
 
 #if 0
       /* not used yet */
       FT_Bool  compatible_widths;
       FT_Bool  symmetrical_smoothing;
       FT_Bool  bgr;
+      FT_Bool  vertical_lcd;
       FT_Bool  subpixel_positioned;
+      FT_Bool  gray_cleartype;
 #endif
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
@@ -2122,9 +2217,7 @@
 
       if ( size->bytecode_ready < 0 || size->cvt_ready < 0 )
       {
-        FT_Error  error = tt_size_ready_bytecode( size, pedantic );
-
-
+        error = tt_size_ready_bytecode( size, pedantic );
         if ( error )
           return error;
       }
@@ -2134,8 +2227,7 @@
         return size->cvt_ready;
 
       /* query new execution context */
-      exec = size->debug ? size->context
-                         : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
+      exec = size->context;
       if ( !exec )
         return FT_THROW( Could_Not_Find_Context );
 
@@ -2143,33 +2235,35 @@
 
       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
       {
-        subpixel = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) !=
-                              FT_RENDER_MODE_MONO               )  &&
-                            SPH_OPTION_SET_SUBPIXEL                );
+        subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) !=
+                                      FT_RENDER_MODE_MONO               )  &&
+                                    SPH_OPTION_SET_SUBPIXEL                );
 
-        if ( subpixel )
+        if ( subpixel_hinting )
           grayscale = FALSE;
         else if ( SPH_OPTION_SET_GRAYSCALE )
         {
-          grayscale = TRUE;
-          subpixel  = FALSE;
+          grayscale        = TRUE;
+          subpixel_hinting = FALSE;
         }
         else
           grayscale = FALSE;
 
         if ( FT_IS_TRICKY( glyph->face ) )
-          subpixel = FALSE;
+          subpixel_hinting = FALSE;
 
-        exec->ignore_x_mode      = subpixel || grayscale;
+        exec->ignore_x_mode      = subpixel_hinting || grayscale;
         exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
         if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 )
           exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
 
 #if 1
         exec->compatible_widths     = SPH_OPTION_SET_COMPATIBLE_WIDTHS;
-        exec->symmetrical_smoothing = FALSE;
+        exec->symmetrical_smoothing = TRUE;
         exec->bgr                   = FALSE;
+        exec->vertical_lcd          = FALSE;
         exec->subpixel_positioned   = TRUE;
+        exec->gray_cleartype        = FALSE;
 #else /* 0 */
         exec->compatible_widths =
           FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
@@ -2180,9 +2274,15 @@
         exec->bgr =
           FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
                    TT_LOAD_BGR );
+        exec->vertical_lcd =
+          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
+                   TT_LOAD_VERTICAL_LCD );
         exec->subpixel_positioned =
           FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
                    TT_LOAD_SUBPIXEL_POSITIONED );
+        exec->gray_cleartype =
+          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
+                   TT_LOAD_GRAY_CLEARTYPE );
 #endif /* 0 */
 
       }
@@ -2195,7 +2295,9 @@
                              FT_RENDER_MODE_MONO );
       }
 
-      TT_Load_Context( exec, face, size );
+      error = TT_Load_Context( exec, face, size );
+      if ( error )
+        return error;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 
@@ -2203,13 +2305,13 @@
       {
         /* a change from mono to subpixel rendering (and vice versa) */
         /* requires a re-execution of the CVT program                */
-        if ( subpixel != exec->subpixel )
+        if ( subpixel_hinting != exec->subpixel_hinting )
         {
           FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
                       " re-executing `prep' table\n" ));
 
-          exec->subpixel = subpixel;
-          reexecute      = TRUE;
+          exec->subpixel_hinting = subpixel_hinting;
+          reexecute              = TRUE;
         }
 
         /* a change from mono to grayscale rendering (and vice versa) */
@@ -2232,7 +2334,7 @@
         /* requires a re-execution of the CVT program                 */
         if ( grayscale != exec->grayscale )
         {
-          FT_TRACE4(( "tt_loader_init: grayscale change,"
+          FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
                       " re-executing `prep' table\n" ));
 
           exec->grayscale = grayscale;
@@ -2242,8 +2344,7 @@
 
       if ( reexecute )
       {
-        FT_UInt   i;
-        FT_Error  error;
+        FT_UInt  i;
 
 
         for ( i = 0; i < size->cvt_size; i++ )
@@ -2253,7 +2354,7 @@
           return error;
       }
 
-      /* see whether the cvt program has disabled hinting */
+      /* check whether the cvt program has disabled hinting */
       if ( exec->GS.instruct_control & 1 )
         load_flags |= FT_LOAD_NO_HINTING;
 
@@ -2261,6 +2362,13 @@
       if ( exec->GS.instruct_control & 2 )
         exec->GS = tt_default_graphics_state;
 
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+      /* 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 )
+        exec->ignore_x_mode = 0;
+#endif
+
       exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
       loader->exec = exec;
       loader->instructions = exec->glyphIns;
@@ -2281,8 +2389,7 @@
 #endif
 
     {
-      FT_Error  error = face->goto_table( face, TTAG_glyf, stream, 0 );
-
+      error = face->goto_table( face, TTAG_glyf, stream, 0 );
 
       if ( FT_ERR_EQ( error, Table_Missing ) )
         loader->glyf_offset = 0;
@@ -2305,7 +2412,7 @@
       loader->gloader = gloader;
     }
 
-    loader->load_flags = load_flags;
+    loader->load_flags = (FT_ULong)load_flags;
 
     loader->face   = (FT_Face)face;
     loader->size   = (FT_Size)size;
@@ -2373,15 +2480,18 @@
           (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
           (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
           glyph->linearHoriAdvance = loader.linear;
-          glyph->linearVertAdvance = loader.top_bearing + loader.bbox.yMax -
-                                       loader.vadvance;
+          glyph->linearVertAdvance = loader.vadvance;
 
-          /* sanity check: if `horiAdvance' in the sbit metric */
-          /* structure isn't set, use `linearHoriAdvance'      */
+          /* sanity checks: if `xxxAdvance' in the sbit metric */
+          /* structure isn't set, use `linearXXXAdvance'      */
           if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
             glyph->metrics.horiAdvance =
               FT_MulFix( glyph->linearHoriAdvance,
                          size->root.metrics.x_scale );
+          if ( !glyph->metrics.vertAdvance && glyph->linearVertAdvance )
+            glyph->metrics.vertAdvance =
+              FT_MulFix( glyph->linearVertAdvance,
+                         size->root.metrics.y_scale );
         }
 
         return FT_Err_Ok;
@@ -2461,7 +2571,7 @@
 
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
-      compute_glyph_metrics( &loader, glyph_index );
+      error = compute_glyph_metrics( &loader, glyph_index );
     }
 
     /* Set the `high precision' bit flag.                           */
diff --git a/src/truetype/ttgload.h b/src/truetype/ttgload.h
index 3f1699e..8e3255e 100644
--- a/src/truetype/ttgload.h
+++ b/src/truetype/ttgload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType Glyph Loader (specification).                               */
 /*                                                                         */
-/*  Copyright 1996-2006, 2008, 2011 by                                     */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index 7899d36..2b12483 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType GX Font Variation loader                                    */
 /*                                                                         */
-/*  Copyright 2004-2013 by                                                 */
+/*  Copyright 2004-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, Werner Lemberg, and George Williams.     */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -20,7 +20,7 @@
   /*                                                                       */
   /* Apple documents the `fvar', `gvar', `cvar', and `avar' tables at      */
   /*                                                                       */
-  /*   http://developer.apple.com/fonts/TTRefMan/RM06/Chap6[fgca]var.html  */
+  /*   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6[fgca]var.html */
   /*                                                                       */
   /* The documentation for `fvar' is inconsistent.  At one point it says   */
   /* that `countSizePairs' should be 3, at another point 2.  It should     */
@@ -60,9 +60,9 @@
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
 
-#define FT_Stream_FTell( stream )  \
+#define FT_Stream_FTell( stream )                         \
           (FT_ULong)( (stream)->cursor - (stream)->base )
-#define FT_Stream_SeekSet( stream, off ) \
+#define FT_Stream_SeekSet( stream, off )                  \
           ( (stream)->cursor = (stream)->base + (off) )
 
 
@@ -96,8 +96,8 @@
 #define ALL_POINTS  (FT_UShort*)~(FT_PtrDist)0
 
 
-#define GX_PT_POINTS_ARE_WORDS      0x80
-#define GX_PT_POINT_RUN_COUNT_MASK  0x7F
+#define GX_PT_POINTS_ARE_WORDS      0x80U
+#define GX_PT_POINT_RUN_COUNT_MASK  0x7FU
 
 
   /*************************************************************************/
@@ -126,52 +126,67 @@
                            FT_UInt   *point_cnt )
   {
     FT_UShort *points = NULL;
-    FT_Int     n;
-    FT_Int     runcnt;
-    FT_Int     i;
-    FT_Int     j;
-    FT_Int     first;
+    FT_UInt    n;
+    FT_UInt    runcnt;
+    FT_UInt    i, j;
+    FT_UShort  first;
     FT_Memory  memory = stream->memory;
     FT_Error   error  = FT_Err_Ok;
 
     FT_UNUSED( error );
 
 
-    *point_cnt = n = FT_GET_BYTE();
+    *point_cnt = 0;
+
+    n = FT_GET_BYTE();
     if ( n == 0 )
       return ALL_POINTS;
 
     if ( n & GX_PT_POINTS_ARE_WORDS )
-      n = FT_GET_BYTE() | ( ( n & GX_PT_POINT_RUN_COUNT_MASK ) << 8 );
+    {
+      n  &= GX_PT_POINT_RUN_COUNT_MASK;
+      n <<= 8;
+      n  |= FT_GET_BYTE();
+    }
 
     if ( FT_NEW_ARRAY( points, n ) )
       return NULL;
 
+    *point_cnt = n;
+
     i = 0;
     while ( i < n )
     {
       runcnt = FT_GET_BYTE();
       if ( runcnt & GX_PT_POINTS_ARE_WORDS )
       {
-        runcnt = runcnt & GX_PT_POINT_RUN_COUNT_MASK;
-        first  = points[i++] = FT_GET_USHORT();
+        runcnt     &= GX_PT_POINT_RUN_COUNT_MASK;
+        first       = FT_GET_USHORT();
+        points[i++] = first;
 
-        if ( runcnt < 1 || i + runcnt >= n )
+        if ( runcnt < 1 || i + runcnt > n )
           goto Exit;
 
-        /* first point not included in runcount */
-        for ( j = 0; j < runcnt; ++j )
-          points[i++] = (FT_UShort)( first += FT_GET_USHORT() );
+        /* first point not included in run count */
+        for ( j = 0; j < runcnt; j++ )
+        {
+          first      += FT_GET_USHORT();
+          points[i++] = first;
+        }
       }
       else
       {
-        first = points[i++] = FT_GET_BYTE();
+        first       = FT_GET_BYTE();
+        points[i++] = first;
 
-        if ( runcnt < 1 || i + runcnt >= n )
+        if ( runcnt < 1 || i + runcnt > n )
           goto Exit;
 
-        for ( j = 0; j < runcnt; ++j )
-          points[i++] = (FT_UShort)( first += FT_GET_BYTE() );
+        for ( j = 0; j < runcnt; j++ )
+        {
+          first      += FT_GET_BYTE();
+          points[i++] = first;
+        }
       }
     }
 
@@ -180,12 +195,9 @@
   }
 
 
-  enum
-  {
-    GX_DT_DELTAS_ARE_ZERO      = 0x80,
-    GX_DT_DELTAS_ARE_WORDS     = 0x40,
-    GX_DT_DELTA_RUN_COUNT_MASK = 0x3F
-  };
+#define GX_DT_DELTAS_ARE_ZERO       0x80U
+#define GX_DT_DELTAS_ARE_WORDS      0x40U
+#define GX_DT_DELTA_RUN_COUNT_MASK  0x3FU
 
 
   /*************************************************************************/
@@ -200,7 +212,7 @@
   /* <Input>                                                               */
   /*    stream    :: The data stream.                                      */
   /*                                                                       */
-  /*    delta_cnt :: The number of to be read.                             */
+  /*    delta_cnt :: The number of deltas to be read.                      */
   /*                                                                       */
   /* <Return>                                                              */
   /*    An array of FT_Short containing the deltas for the affected        */
@@ -210,12 +222,11 @@
   /*                                                                       */
   static FT_Short*
   ft_var_readpackeddeltas( FT_Stream  stream,
-                           FT_Offset  delta_cnt )
+                           FT_UInt    delta_cnt )
   {
     FT_Short  *deltas = NULL;
-    FT_UInt    runcnt;
-    FT_Offset  i;
-    FT_UInt    j;
+    FT_UInt    runcnt, cnt;
+    FT_UInt    i, j;
     FT_Memory  memory = stream->memory;
     FT_Error   error  = FT_Err_Ok;
 
@@ -229,34 +240,30 @@
     while ( i < delta_cnt )
     {
       runcnt = FT_GET_BYTE();
+      cnt    = runcnt & GX_DT_DELTA_RUN_COUNT_MASK;
+
       if ( runcnt & GX_DT_DELTAS_ARE_ZERO )
       {
-        /* runcnt zeroes get added */
-        for ( j = 0;
-              j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt;
-              ++j )
+        /* `runcnt' zeroes get added */
+        for ( j = 0; j <= cnt && i < delta_cnt; j++ )
           deltas[i++] = 0;
       }
       else if ( runcnt & GX_DT_DELTAS_ARE_WORDS )
       {
-        /* runcnt shorts from the stack */
-        for ( j = 0;
-              j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt;
-              ++j )
+        /* `runcnt' shorts from the stack */
+        for ( j = 0; j <= cnt && i < delta_cnt; j++ )
           deltas[i++] = FT_GET_SHORT();
       }
       else
       {
-        /* runcnt signed bytes from the stack */
-        for ( j = 0;
-              j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) && i < delta_cnt;
-              ++j )
+        /* `runcnt' signed bytes from the stack */
+        for ( j = 0; j <= cnt && i < delta_cnt; j++ )
           deltas[i++] = FT_GET_CHAR();
       }
 
-      if ( j <= ( runcnt & GX_DT_DELTA_RUN_COUNT_MASK ) )
+      if ( j <= cnt )
       {
-        /* Bad format */
+        /* bad format */
         FT_FREE( deltas );
         return NULL;
       }
@@ -281,12 +288,12 @@
   static void
   ft_var_load_avar( TT_Face  face )
   {
-    FT_Stream       stream = FT_FACE_STREAM(face);
+    FT_Stream       stream = FT_FACE_STREAM( face );
     FT_Memory       memory = stream->memory;
     GX_Blend        blend  = face->blend;
     GX_AVarSegment  segment;
     FT_Error        error = FT_Err_Ok;
-    FT_ULong        version;
+    FT_Long         version;
     FT_Long         axisCount;
     FT_Int          i, j;
     FT_ULong        table_len;
@@ -294,9 +301,15 @@
     FT_UNUSED( error );
 
 
+    FT_TRACE2(( "AVAR " ));
+
     blend->avar_checked = TRUE;
-    if ( (error = face->goto_table( face, TTAG_avar, stream, &table_len )) != 0 )
+    error = face->goto_table( face, TTAG_avar, stream, &table_len );
+    if ( error )
+    {
+      FT_TRACE2(( "is missing\n" ));
       return;
+    }
 
     if ( FT_FRAME_ENTER( table_len ) )
       return;
@@ -304,23 +317,36 @@
     version   = FT_GET_LONG();
     axisCount = FT_GET_LONG();
 
-    if ( version != 0x00010000L                       ||
-         axisCount != (FT_Long)blend->mmvar->num_axis )
+    if ( version != 0x00010000L )
+    {
+      FT_TRACE2(( "bad table version\n" ));
       goto Exit;
+    }
+
+    FT_TRACE2(( "loaded\n" ));
+
+    if ( axisCount != (FT_Long)blend->mmvar->num_axis )
+    {
+      FT_TRACE2(( "ft_var_load_avar: number of axes in `avar' and `cvar'\n"
+                  "                  table are different\n" ));
+      goto Exit;
+    }
 
     if ( FT_NEW_ARRAY( blend->avar_segment, axisCount ) )
       goto Exit;
 
     segment = &blend->avar_segment[0];
-    for ( i = 0; i < axisCount; ++i, ++segment )
+    for ( i = 0; i < axisCount; i++, segment++ )
     {
+      FT_TRACE5(( "  axis %d:\n", i ));
+
       segment->pairCount = FT_GET_USHORT();
       if ( FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) )
       {
         /* Failure.  Free everything we have done so far.  We must do */
         /* it right now since loading the `avar' table is optional.   */
 
-        for ( j = i - 1; j >= 0; --j )
+        for ( j = i - 1; j >= 0; j-- )
           FT_FREE( blend->avar_segment[j].correspondence );
 
         FT_FREE( blend->avar_segment );
@@ -328,13 +354,18 @@
         goto Exit;
       }
 
-      for ( j = 0; j < segment->pairCount; ++j )
+      for ( j = 0; j < segment->pairCount; j++ )
       {
-        segment->correspondence[j].fromCoord =
-          FT_GET_SHORT() << 2;    /* convert to Fixed */
-        segment->correspondence[j].toCoord =
-          FT_GET_SHORT()<<2;    /* convert to Fixed */
+        /* convert to Fixed */
+        segment->correspondence[j].fromCoord = FT_GET_SHORT() << 2;
+        segment->correspondence[j].toCoord   = FT_GET_SHORT() << 2;
+
+        FT_TRACE5(( "    mapping %.4f to %.4f\n",
+                    segment->correspondence[j].fromCoord / 65536.0,
+                    segment->correspondence[j].toCoord / 65536.0 ));
       }
+
+      FT_TRACE5(( "\n" ));
     }
 
   Exit:
@@ -361,8 +392,8 @@
   /*    ft_var_load_gvar                                                   */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Parses the `gvar' table if present.  If `fvar' is there, `gvar'    */
-  /*    had better be there too.                                           */
+  /*    Parse the `gvar' table if present.  If `fvar' is there, `gvar' had */
+  /*    better be there too.                                               */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    face :: The font face.                                             */
@@ -373,7 +404,7 @@
   static FT_Error
   ft_var_load_gvar( TT_Face  face )
   {
-    FT_Stream     stream = FT_FACE_STREAM(face);
+    FT_Stream     stream = FT_FACE_STREAM( face );
     FT_Memory     memory = stream->memory;
     GX_Blend      blend  = face->blend;
     FT_Error      error;
@@ -400,8 +431,17 @@
       FT_FRAME_END
     };
 
-    if ( (error = face->goto_table( face, TTAG_gvar, stream, &table_len )) != 0 )
+
+    FT_TRACE2(( "GVAR " ));
+
+    if ( ( error = face->goto_table( face,
+                                     TTAG_gvar,
+                                     stream,
+                                     &table_len ) ) != 0 )
+    {
+      FT_TRACE2(( "is missing\n" ));
       goto Exit;
+    }
 
     gvar_start = FT_STREAM_POS( );
     if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) )
@@ -411,13 +451,26 @@
     blend->gv_glyphcnt = gvar_head.glyphCount;
     offsetToData       = gvar_start + gvar_head.offsetToData;
 
-    if ( gvar_head.version   != (FT_Long)0x00010000L              ||
-         gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis )
+    if ( gvar_head.version != 0x00010000L )
     {
+      FT_TRACE1(( "bad table version\n" ));
       error = FT_THROW( Invalid_Table );
       goto Exit;
     }
 
+    FT_TRACE2(( "loaded\n" ));
+
+    if ( gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis )
+    {
+      FT_TRACE1(( "ft_var_load_gvar: number of axes in `gvar' and `cvar'\n"
+                  "                  table are different\n" ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    FT_TRACE5(( "gvar: there are %d shared coordinates:\n",
+                blend->tuplecount ));
+
     if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) )
       goto Exit;
 
@@ -427,8 +480,8 @@
       if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) )
         goto Exit;
 
-      for ( i = 0; i <= blend->gv_glyphcnt; ++i )
-        blend->glyphoffsets[i] = offsetToData + FT_GET_LONG();
+      for ( i = 0; i <= blend->gv_glyphcnt; i++ )
+        blend->glyphoffsets[i] = offsetToData + FT_GET_ULONG();
 
       FT_FRAME_EXIT();
     }
@@ -438,9 +491,9 @@
       if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) )
         goto Exit;
 
-      for ( i = 0; i <= blend->gv_glyphcnt; ++i )
+      for ( i = 0; i <= blend->gv_glyphcnt; i++ )
         blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2;
-                                              /* XXX: Undocumented: `*2'! */
+                                               /* XXX: Undocumented: `*2'! */
 
       FT_FRAME_EXIT();
     }
@@ -451,14 +504,24 @@
                          gvar_head.axisCount * blend->tuplecount ) )
         goto Exit;
 
-      if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord )       ||
-           FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L )                   )
+      if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord )         ||
+           FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) )
         goto Exit;
 
-      for ( i = 0; i < blend->tuplecount; ++i )
-        for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; ++j )
+      for ( i = 0; i < blend->tuplecount; i++ )
+      {
+        FT_TRACE5(( "  [ " ));
+        for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; j++ )
+        {
           blend->tuplecoords[i * gvar_head.axisCount + j] =
             FT_GET_SHORT() << 2;                /* convert to FT_Fixed */
+          FT_TRACE5(( "%.4f ",
+            blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 ));
+        }
+        FT_TRACE5(( "]\n" ));
+      }
+
+      FT_TRACE5(( "\n" ));
 
       FT_FRAME_EXIT();
     }
@@ -506,48 +569,83 @@
     FT_Fixed  apply = 0x10000L;
 
 
-    for ( i = 0; i < blend->num_axis; ++i )
+    for ( i = 0; i < blend->num_axis; i++ )
     {
-      if ( tuple_coords[i] == 0 )
-        /* It's not clear why (for intermediate tuples) we don't need     */
-        /* to check against start/end -- the documentation says we don't. */
-        /* Similarly, it's unclear why we don't need to scale along the   */
-        /* axis.                                                          */
-        continue;
+      FT_TRACE6(( "    axis coordinate %d (%.4f):\n",
+                  i, blend->normalizedcoords[i] / 65536.0 ));
 
-      else if ( blend->normalizedcoords[i] == 0                           ||
-                ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) ||
+      /* It's not clear why (for intermediate tuples) we don't need     */
+      /* to check against start/end -- the documentation says we don't. */
+      /* Similarly, it's unclear why we don't need to scale along the   */
+      /* axis.                                                          */
+
+      if ( tuple_coords[i] == 0 )
+      {
+        FT_TRACE6(( "      tuple coordinate is zero, ignored\n", i ));
+        continue;
+      }
+
+      else if ( blend->normalizedcoords[i] == 0 )
+      {
+        FT_TRACE6(( "      axis coordinate is zero, stop\n" ));
+        apply = 0;
+        break;
+      }
+
+      else if ( ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) ||
                 ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) )
       {
+        FT_TRACE6(( "      tuple coordinate value %.4f is exceeded, stop\n",
+                    tuple_coords[i] / 65536.0 ));
         apply = 0;
         break;
       }
 
       else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) )
+      {
+        FT_TRACE6(( "      tuple coordinate value %.4f fits\n",
+                    tuple_coords[i] / 65536.0 ));
         /* not an intermediate tuple */
         apply = FT_MulFix( apply,
                            blend->normalizedcoords[i] > 0
                              ? blend->normalizedcoords[i]
                              : -blend->normalizedcoords[i] );
+      }
 
-      else if ( blend->normalizedcoords[i] <= im_start_coords[i] ||
-                blend->normalizedcoords[i] >= im_end_coords[i]   )
+      else if ( blend->normalizedcoords[i] < im_start_coords[i] ||
+                blend->normalizedcoords[i] > im_end_coords[i]   )
       {
+        FT_TRACE6(( "      intermediate tuple range [%.4f;%.4f] is exceeded,"
+                    " stop\n",
+                    im_start_coords[i] / 65536.0,
+                    im_end_coords[i] / 65536.0 ));
         apply = 0;
         break;
       }
 
       else if ( blend->normalizedcoords[i] < tuple_coords[i] )
+      {
+        FT_TRACE6(( "      intermediate tuple range [%.4f;%.4f] fits\n",
+                    im_start_coords[i] / 65536.0,
+                    im_end_coords[i] / 65536.0 ));
         apply = FT_MulDiv( apply,
                            blend->normalizedcoords[i] - im_start_coords[i],
                            tuple_coords[i] - im_start_coords[i] );
+      }
 
       else
+      {
+        FT_TRACE6(( "      intermediate tuple range [%.4f;%.4f] fits\n",
+                    im_start_coords[i] / 65536.0,
+                    im_end_coords[i] / 65536.0 ));
         apply = FT_MulDiv( apply,
                            im_end_coords[i] - blend->normalizedcoords[i],
                            im_end_coords[i] - tuple_coords[i] );
+      }
     }
 
+    FT_TRACE6(( "    apply factor is %.4f\n", apply / 65536.0 ));
+
     return apply;
   }
 
@@ -577,9 +675,9 @@
   typedef struct  fvar_axis_
   {
     FT_ULong   axisTag;
-    FT_ULong   minValue;
-    FT_ULong   defaultValue;
-    FT_ULong   maxValue;
+    FT_Fixed   minValue;
+    FT_Fixed   defaultValue;
+    FT_Fixed   maxValue;
     FT_UShort  flags;
     FT_UShort  nameID;
 
@@ -647,25 +745,37 @@
 
       FT_FRAME_START( 20 ),
         FT_FRAME_ULONG ( axisTag ),
-        FT_FRAME_ULONG ( minValue ),
-        FT_FRAME_ULONG ( defaultValue ),
-        FT_FRAME_ULONG ( maxValue ),
+        FT_FRAME_LONG  ( minValue ),
+        FT_FRAME_LONG  ( defaultValue ),
+        FT_FRAME_LONG  ( maxValue ),
         FT_FRAME_USHORT( flags ),
         FT_FRAME_USHORT( nameID ),
       FT_FRAME_END
     };
 
 
+    /* read the font data and set up the internal representation */
+    /* if not already done                                       */
+
     if ( face->blend == NULL )
     {
-      /* both `fvar' and `gvar' must be present */
-      if ( (error = face->goto_table( face, TTAG_gvar,
-                                      stream, &table_len )) != 0 )
-        goto Exit;
+      FT_TRACE2(( "FVAR " ));
 
-      if ( (error = face->goto_table( face, TTAG_fvar,
-                                      stream, &table_len )) != 0 )
+      /* both `fvar' and `gvar' must be present */
+      if ( ( error = face->goto_table( face, TTAG_gvar,
+                                       stream, &table_len ) ) != 0 )
+      {
+        FT_TRACE1(( "\n"
+                    "TT_Get_MM_Var: `gvar' table is missing\n" ));
         goto Exit;
+      }
+
+      if ( ( error = face->goto_table( face, TTAG_fvar,
+                                       stream, &table_len ) ) != 0 )
+      {
+        FT_TRACE1(( "is missing\n" ));
+        goto Exit;
+      }
 
       fvar_start = FT_STREAM_POS( );
 
@@ -673,7 +783,12 @@
         goto Exit;
 
       if ( fvar_head.version != (FT_Long)0x00010000L                      ||
+#if 0
+           /* fonts like `JamRegular.ttf' have an incorrect value for */
+           /* `countSizePairs'; since value 2 is hard-coded in `fvar' */
+           /* version 1.0, we simply ignore it                        */
            fvar_head.countSizePairs != 2                                  ||
+#endif
            fvar_head.axisSize != 20                                       ||
            /* axisCount limit implied by 16-bit instanceSize */
            fvar_head.axisCount > 0x3FFE                                   ||
@@ -683,10 +798,16 @@
            fvar_head.offsetToData + fvar_head.axisCount * 20U +
              fvar_head.instanceCount * fvar_head.instanceSize > table_len )
       {
+        FT_TRACE1(( "\n"
+                    "TT_Get_MM_Var: invalid `fvar' header\n" ));
         error = FT_THROW( Invalid_Table );
         goto Exit;
       }
 
+      FT_TRACE2(( "loaded\n" ));
+
+      FT_TRACE5(( "number of GX style axes: %d\n", fvar_head.axisCount ));
+
       if ( FT_NEW( face->blend ) )
         goto Exit;
 
@@ -702,6 +823,9 @@
         goto Exit;
       face->blend->mmvar = mmvar;
 
+      /* set up pointers and offsets into the `mmvar' array; */
+      /* the data gets filled in later on                    */
+
       mmvar->num_axis =
         fvar_head.axisCount;
       mmvar->num_designs =
@@ -711,30 +835,32 @@
       mmvar->num_namedstyles =
         fvar_head.instanceCount;
       mmvar->axis =
-        (FT_Var_Axis*)&(mmvar[1]);
+        (FT_Var_Axis*)&( mmvar[1] );
       mmvar->namedstyle =
-        (FT_Var_Named_Style*)&(mmvar->axis[fvar_head.axisCount]);
+        (FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] );
 
       next_coords =
-        (FT_Fixed*)&(mmvar->namedstyle[fvar_head.instanceCount]);
-      for ( i = 0; i < fvar_head.instanceCount; ++i )
+        (FT_Fixed*)&( mmvar->namedstyle[fvar_head.instanceCount] );
+      for ( i = 0; i < fvar_head.instanceCount; i++ )
       {
         mmvar->namedstyle[i].coords  = next_coords;
         next_coords                 += fvar_head.axisCount;
       }
 
       next_name = (FT_String*)next_coords;
-      for ( i = 0; i < fvar_head.axisCount; ++i )
+      for ( i = 0; i < fvar_head.axisCount; i++ )
       {
         mmvar->axis[i].name  = next_name;
         next_name           += 5;
       }
 
+      /* now fill in the data */
+
       if ( FT_STREAM_SEEK( fvar_start + fvar_head.offsetToData ) )
         goto Exit;
 
       a = mmvar->axis;
-      for ( i = 0; i < fvar_head.axisCount; ++i )
+      for ( i = 0; i < fvar_head.axisCount; i++ )
       {
         GX_FVar_Axis  axis_rec;
 
@@ -742,22 +868,30 @@
         if ( FT_STREAM_READ_FIELDS( fvaraxis_fields, &axis_rec ) )
           goto Exit;
         a->tag     = axis_rec.axisTag;
-        a->minimum = axis_rec.minValue;     /* A Fixed */
-        a->def     = axis_rec.defaultValue; /* A Fixed */
-        a->maximum = axis_rec.maxValue;     /* A Fixed */
+        a->minimum = axis_rec.minValue;
+        a->def     = axis_rec.defaultValue;
+        a->maximum = axis_rec.maxValue;
         a->strid   = axis_rec.nameID;
 
         a->name[0] = (FT_String)(   a->tag >> 24 );
         a->name[1] = (FT_String)( ( a->tag >> 16 ) & 0xFF );
         a->name[2] = (FT_String)( ( a->tag >>  8 ) & 0xFF );
         a->name[3] = (FT_String)( ( a->tag       ) & 0xFF );
-        a->name[4] = 0;
+        a->name[4] = '\0';
 
-        ++a;
+        FT_TRACE5(( "  \"%s\": minimum=%.4f, default=%.4f, maximum=%.4f\n",
+                    a->name,
+                    a->minimum / 65536.0,
+                    a->def / 65536.0,
+                    a->maximum / 65536.0 ));
+
+        a++;
       }
 
+      FT_TRACE5(( "\n" ));
+
       ns = mmvar->namedstyle;
-      for ( i = 0; i < fvar_head.instanceCount; ++i, ++ns )
+      for ( i = 0; i < fvar_head.instanceCount; i++, ns++ )
       {
         if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) )
           goto Exit;
@@ -765,13 +899,15 @@
         ns->strid       =    FT_GET_USHORT();
         (void) /* flags = */ FT_GET_USHORT();
 
-        for ( j = 0; j < fvar_head.axisCount; ++j )
-          ns->coords[j] = FT_GET_ULONG();     /* A Fixed */
+        for ( j = 0; j < fvar_head.axisCount; j++ )
+          ns->coords[j] = FT_GET_LONG();
 
         FT_FRAME_EXIT();
       }
     }
 
+    /* fill the output array if requested */
+
     if ( master != NULL )
     {
       FT_UInt  n;
@@ -782,36 +918,36 @@
       FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len );
 
       mmvar->axis =
-        (FT_Var_Axis*)&(mmvar[1]);
+        (FT_Var_Axis*)&( mmvar[1] );
       mmvar->namedstyle =
-        (FT_Var_Named_Style*)&(mmvar->axis[mmvar->num_axis]);
+        (FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] );
       next_coords =
-        (FT_Fixed*)&(mmvar->namedstyle[mmvar->num_namedstyles]);
+        (FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] );
 
-      for ( n = 0; n < mmvar->num_namedstyles; ++n )
+      for ( n = 0; n < mmvar->num_namedstyles; n++ )
       {
         mmvar->namedstyle[n].coords  = next_coords;
         next_coords                 += mmvar->num_axis;
       }
 
-      a = mmvar->axis;
+      a         = mmvar->axis;
       next_name = (FT_String*)next_coords;
-      for ( n = 0; n < mmvar->num_axis; ++n )
+      for ( n = 0; n < mmvar->num_axis; n++ )
       {
         a->name = next_name;
 
         /* standard PostScript names for some standard apple tags */
         if ( a->tag == TTAG_wght )
-          a->name = (char *)"Weight";
+          a->name = (char*)"Weight";
         else if ( a->tag == TTAG_wdth )
-          a->name = (char *)"Width";
+          a->name = (char*)"Width";
         else if ( a->tag == TTAG_opsz )
-          a->name = (char *)"OpticalSize";
+          a->name = (char*)"OpticalSize";
         else if ( a->tag == TTAG_slnt )
-          a->name = (char *)"Slant";
+          a->name = (char*)"Slant";
 
         next_name += 5;
-        ++a;
+        a++;
       }
 
       *master = mmvar;
@@ -837,9 +973,12 @@
   /*                  Initialize the blend structure with `gvar' data.     */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    num_coords :: Must be the axis count of the font.                  */
+  /*    num_coords :: The number of available coordinates.  If it is       */
+  /*                  larger than the number of axes, ignore the excess    */
+  /*                  values.  If it is smaller than the number of axes,   */
+  /*                  use the default value (0) for the remaining axes.    */
   /*                                                                       */
-  /*    coords     :: An array of num_coords, each between [-1,1].         */
+  /*    coords     :: An array of `num_coords', each between [-1,1].       */
   /*                                                                       */
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
@@ -868,33 +1007,44 @@
 
     if ( face->blend == NULL )
     {
-      if ( (error = TT_Get_MM_Var( face, NULL)) != 0 )
+      if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 )
         goto Exit;
     }
 
     blend = face->blend;
     mmvar = blend->mmvar;
 
-    if ( num_coords != mmvar->num_axis )
+    if ( num_coords > mmvar->num_axis )
     {
-      error = FT_THROW( Invalid_Argument );
-      goto Exit;
+      FT_TRACE2(( "TT_Set_MM_Blend: only using first %d of %d coordinates\n",
+                  mmvar->num_axis, num_coords ));
+      num_coords = mmvar->num_axis;
     }
 
-    for ( i = 0; i < num_coords; ++i )
+    FT_TRACE5(( "normalized design coordinates:\n" ));
+
+    for ( i = 0; i < num_coords; i++ )
+    {
+      FT_TRACE5(( "  %.4f\n", coords[i] / 65536.0 ));
       if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L )
       {
+        FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.4f\n"
+                    "                 is out of range [-1;1]\n",
+                    coords[i] / 65536.0 ));
         error = FT_THROW( Invalid_Argument );
         goto Exit;
       }
+    }
+
+    FT_TRACE5(( "\n" ));
 
     if ( blend->glyphoffsets == NULL )
-      if ( (error = ft_var_load_gvar( face )) != 0 )
+      if ( ( error = ft_var_load_gvar( face ) ) != 0 )
         goto Exit;
 
     if ( blend->normalizedcoords == NULL )
     {
-      if ( FT_NEW_ARRAY( blend->normalizedcoords, num_coords ) )
+      if ( FT_NEW_ARRAY( blend->normalizedcoords, mmvar->num_axis ) )
         goto Exit;
 
       manageCvt = mcvt_modify;
@@ -906,7 +1056,8 @@
     else
     {
       manageCvt = mcvt_retain;
-      for ( i = 0; i < num_coords; ++i )
+
+      for ( i = 0; i < num_coords; i++ )
       {
         if ( blend->normalizedcoords[i] != coords[i] )
         {
@@ -915,13 +1066,22 @@
         }
       }
 
+      for ( ; i < mmvar->num_axis; i++ )
+      {
+        if ( blend->normalizedcoords[i] != 0 )
+        {
+          manageCvt = mcvt_load;
+          break;
+        }
+      }
+
       /* If we don't change the blend coords then we don't need to do  */
       /* anything to the cvt table.  It will be correct.  Otherwise we */
       /* no longer have the original cvt (it was modified when we set  */
       /* the blend last time), so we must reload and then modify it.   */
     }
 
-    blend->num_axis = num_coords;
+    blend->num_axis = mmvar->num_axis;
     FT_MEM_COPY( blend->normalizedcoords,
                  coords,
                  num_coords * sizeof ( FT_Fixed ) );
@@ -938,13 +1098,13 @@
         FT_FREE( face->cvt );
         face->cvt = NULL;
 
-        tt_face_load_cvt( face, face->root.stream );
+        error = tt_face_load_cvt( face, face->root.stream );
         break;
 
       case mcvt_modify:
         /* The original cvt table is in memory.  All we need to do is */
         /* apply the `cvar' table (if any).                           */
-        tt_face_vary_cvt( face, face->root.stream );
+        error = tt_face_vary_cvt( face, face->root.stream );
         break;
 
       case mcvt_retain:
@@ -973,7 +1133,10 @@
   /*                  Initialize the blend struct with `gvar' data.        */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    num_coords :: This must be the axis count of the font.             */
+  /*    num_coords :: The number of available coordinates.  If it is       */
+  /*                  larger than the number of axes, ignore the excess    */
+  /*                  values.  If it is smaller than the number of axes,   */
+  /*                  use the default values for the remaining axes.       */
   /*                                                                       */
   /*    coords     :: A coordinate array with `num_coords' elements.       */
   /*                                                                       */
@@ -997,17 +1160,19 @@
 
     if ( face->blend == NULL )
     {
-      if ( (error = TT_Get_MM_Var( face, NULL )) != 0 )
+      if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 )
         goto Exit;
     }
 
     blend = face->blend;
     mmvar = blend->mmvar;
 
-    if ( num_coords != mmvar->num_axis )
+    if ( num_coords > mmvar->num_axis )
     {
-      error = FT_THROW( Invalid_Argument );
-      goto Exit;
+      FT_TRACE2(( "TT_Set_Var_Design:"
+                  " only using first %d of %d coordinates\n",
+                  mmvar->num_axis, num_coords ));
+      num_coords = mmvar->num_axis;
     }
 
     /* Axis normalization is a two stage process.  First we normalize */
@@ -1017,32 +1182,52 @@
     if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) )
       goto Exit;
 
+    FT_TRACE5(( "design coordinates:\n" ));
+
     a = mmvar->axis;
-    for ( i = 0; i < mmvar->num_axis; ++i, ++a )
+    for ( i = 0; i < num_coords; i++, a++ )
     {
+      FT_TRACE5(( "  %.4f\n", coords[i] / 65536.0 ));
       if ( coords[i] > a->maximum || coords[i] < a->minimum )
       {
+        FT_TRACE1(( "TT_Set_Var_Design: normalized design coordinate %.4f\n"
+                    "                   is out of range [%.4f;%.4f]\n",
+                    coords[i] / 65536.0,
+                    a->minimum / 65536.0,
+                    a->maximum / 65536.0 ));
         error = FT_THROW( Invalid_Argument );
         goto Exit;
       }
 
       if ( coords[i] < a->def )
-        normalized[i] = -FT_DivFix( coords[i] - a->def, a->minimum - a->def );
+        normalized[i] = -FT_DivFix( coords[i] - a->def,
+                                    a->minimum - a->def );
       else if ( a->maximum == a->def )
         normalized[i] = 0;
       else
-        normalized[i] = FT_DivFix( coords[i] - a->def, a->maximum - a->def );
+        normalized[i] = FT_DivFix( coords[i] - a->def,
+                                   a->maximum - a->def );
     }
 
+    FT_TRACE5(( "\n" ));
+
+    for ( ; i < mmvar->num_axis; i++ )
+      normalized[i] = 0;
+
     if ( !blend->avar_checked )
       ft_var_load_avar( face );
 
     if ( blend->avar_segment != NULL )
     {
+      FT_TRACE5(( "normalized design coordinates"
+                  " before applying `avar' data:\n" ));
+
       av = blend->avar_segment;
-      for ( i = 0; i < mmvar->num_axis; ++i, ++av )
+      for ( i = 0; i < mmvar->num_axis; i++, av++ )
       {
-        for ( j = 1; j < (FT_UInt)av->pairCount; ++j )
+        for ( j = 1; j < (FT_UInt)av->pairCount; j++ )
+        {
+          FT_TRACE5(( "  %.4f\n", normalized[i] / 65536.0 ));
           if ( normalized[i] < av->correspondence[j].fromCoord )
           {
             normalized[i] =
@@ -1054,10 +1239,11 @@
               av->correspondence[j - 1].toCoord;
             break;
           }
+        }
       }
     }
 
-    error = TT_Set_MM_Blend( face, num_coords, normalized );
+    error = TT_Set_MM_Blend( face, mmvar->num_axis, normalized );
 
   Exit:
     FT_FREE( normalized );
@@ -1120,16 +1306,16 @@
 
     if ( blend == NULL )
     {
-      FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" ));
-
+      FT_TRACE2(( "\n"
+                  "tt_face_vary_cvt: no blend specified\n" ));
       error = FT_Err_Ok;
       goto Exit;
     }
 
     if ( face->cvt == NULL )
     {
-      FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" ));
-
+      FT_TRACE2(( "\n"
+                  "tt_face_vary_cvt: no `cvt ' table\n" ));
       error = FT_Err_Ok;
       goto Exit;
     }
@@ -1158,6 +1344,8 @@
       goto FExit;
     }
 
+    FT_TRACE2(( "loaded\n" ));
+
     if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis )    ||
          FT_NEW_ARRAY( im_start_coords, blend->num_axis ) ||
          FT_NEW_ARRAY( im_end_coords, blend->num_axis )   )
@@ -1170,13 +1358,17 @@
     /* tuplecount, but John Jenkins says that shared points don't apply */
     /* to `cvar', and no other flags are defined.                       */
 
-    for ( i = 0; i < ( tupleCount & 0xFFF ); ++i )
+    FT_TRACE5(( "cvar: there are %d tuples:\n", tupleCount ));
+
+    for ( i = 0; i < ( tupleCount & 0xFFF ); i++ )
     {
       FT_UInt   tupleDataSize;
       FT_UInt   tupleIndex;
       FT_Fixed  apply;
 
 
+      FT_TRACE6(( "  tuple %d:\n", i ));
+
       tupleDataSize = FT_GET_USHORT();
       tupleIndex    = FT_GET_USHORT();
 
@@ -1185,7 +1377,7 @@
 
       if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
       {
-        for ( j = 0; j < blend->num_axis; ++j )
+        for ( j = 0; j < blend->num_axis; j++ )
           tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from        */
                                                  /* short frac to fixed */
       }
@@ -1194,7 +1386,7 @@
         /* skip this tuple; it makes no sense */
 
         if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
-          for ( j = 0; j < 2 * blend->num_axis; ++j )
+          for ( j = 0; j < 2 * blend->num_axis; j++ )
             (void)FT_GET_SHORT();
 
         offsetToData += tupleDataSize;
@@ -1203,9 +1395,9 @@
 
       if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
       {
-        for ( j = 0; j < blend->num_axis; ++j )
+        for ( j = 0; j < blend->num_axis; j++ )
           im_start_coords[j] = FT_GET_SHORT() << 2;
-        for ( j = 0; j < blend->num_axis; ++j )
+        for ( j = 0; j < blend->num_axis; j++ )
           im_end_coords[j] = FT_GET_SHORT() << 2;
       }
 
@@ -1233,25 +1425,74 @@
                                              point_count == 0 ? face->cvt_size
                                                               : point_count );
       if ( localpoints == NULL || deltas == NULL )
-        /* failure, ignore it */;
+        ; /* failure, ignore it */
 
       else if ( localpoints == ALL_POINTS )
       {
+#ifdef FT_DEBUG_LEVEL_TRACE
+        int  count = 0;
+#endif
+
+
+        FT_TRACE7(( "    CVT deltas:\n" ));
+
         /* this means that there are deltas for every entry in cvt */
-        for ( j = 0; j < face->cvt_size; ++j )
-          face->cvt[j] = (FT_Short)( face->cvt[j] +
+        for ( j = 0; j < face->cvt_size; j++ )
+        {
+          FT_Long  orig_cvt = face->cvt[j];
+
+
+          face->cvt[j] = (FT_Short)( orig_cvt +
                                      FT_MulFix( deltas[j], apply ) );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+          if ( orig_cvt != face->cvt[j] )
+          {
+            FT_TRACE7(( "      %d: %d -> %d\n",
+                        j, orig_cvt, face->cvt[j] ));
+            count++;
+          }
+#endif
+        }
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+        if ( !count )
+          FT_TRACE7(( "      none\n" ));
+#endif
       }
 
       else
       {
-        for ( j = 0; j < point_count; ++j )
-        {
-          int  pindex = localpoints[j];
+#ifdef FT_DEBUG_LEVEL_TRACE
+        int  count = 0;
+#endif
 
-          face->cvt[pindex] = (FT_Short)( face->cvt[pindex] +
+
+        FT_TRACE7(( "    CVT deltas:\n" ));
+
+        for ( j = 0; j < point_count; j++ )
+        {
+          int      pindex   = localpoints[j];
+          FT_Long  orig_cvt = face->cvt[pindex];
+
+
+          face->cvt[pindex] = (FT_Short)( orig_cvt +
                                           FT_MulFix( deltas[j], apply ) );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+          if ( orig_cvt != face->cvt[pindex] )
+          {
+            FT_TRACE7(( "      %d: %d -> %d\n",
+                        pindex, orig_cvt, face->cvt[pindex] ));
+            count++;
+          }
+#endif
         }
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+        if ( !count )
+          FT_TRACE7(( "      none\n" ));
+#endif
       }
 
       if ( localpoints != ALL_POINTS )
@@ -1263,6 +1504,8 @@
       FT_Stream_SeekSet( stream, here );
     }
 
+    FT_TRACE5(( "\n" ));
+
   FExit:
     FT_FRAME_EXIT();
 
@@ -1275,13 +1518,230 @@
   }
 
 
+  /* Shift the original coordinates of all points between indices `p1' */
+  /* and `p2', using the same difference as given by index `ref'.      */
+
+  /* modeled after `af_iup_shift' */
+
+  static void
+  tt_delta_shift( int         p1,
+                  int         p2,
+                  int         ref,
+                  FT_Vector*  in_points,
+                  FT_Vector*  out_points )
+  {
+    int        p;
+    FT_Vector  delta;
+
+
+    delta.x = out_points[ref].x - in_points[ref].x;
+    delta.y = out_points[ref].y - in_points[ref].y;
+
+    if ( delta.x == 0 && delta.y == 0 )
+      return;
+
+    for ( p = p1; p < ref; p++ )
+    {
+      out_points[p].x += delta.x;
+      out_points[p].y += delta.y;
+    }
+
+    for ( p = ref + 1; p <= p2; p++ )
+    {
+      out_points[p].x += delta.x;
+      out_points[p].y += delta.y;
+    }
+  }
+
+
+  /* Interpolate the original coordinates of all points with indices */
+  /* between `p1' and `p2', using `ref1' and `ref2' as the reference */
+  /* point indices.                                                  */
+
+  /* modeled after `af_iup_interp', `_iup_worker_interpolate', and */
+  /* `Ins_IUP'                                                     */
+
+  static void
+  tt_delta_interpolate( int         p1,
+                        int         p2,
+                        int         ref1,
+                        int         ref2,
+                        FT_Vector*  in_points,
+                        FT_Vector*  out_points )
+  {
+    int  p, i;
+
+    FT_Pos  out, in1, in2, out1, out2, d1, d2;
+
+
+    if ( p1 > p2 )
+      return;
+
+    /* handle both horizontal and vertical coordinates */
+    for ( i = 0; i <= 1; i++ )
+    {
+      /* shift array pointers so that we can access `foo.y' as `foo.x' */
+      in_points  = (FT_Vector*)( (FT_Pos*)in_points + i );
+      out_points = (FT_Vector*)( (FT_Pos*)out_points + i );
+
+      if ( in_points[ref1].x > in_points[ref2].x )
+      {
+        p    = ref1;
+        ref1 = ref2;
+        ref2 = p;
+      }
+
+      in1  = in_points[ref1].x;
+      in2  = in_points[ref2].x;
+      out1 = out_points[ref1].x;
+      out2 = out_points[ref2].x;
+      d1   = out1 - in1;
+      d2   = out2 - in2;
+
+      if ( out1 == out2 || in1 == in2 )
+      {
+        for ( p = p1; p <= p2; p++ )
+        {
+          out = in_points[p].x;
+
+          if ( out <= in1 )
+            out += d1;
+          else if ( out >= in2 )
+            out += d2;
+          else
+            out = out1;
+
+          out_points[p].x = out;
+        }
+      }
+      else
+      {
+        FT_Fixed  scale = FT_DivFix( out2 - out1, in2 - in1 );
+
+
+        for ( p = p1; p <= p2; p++ )
+        {
+          out = in_points[p].x;
+
+          if ( out <= in1 )
+            out += d1;
+          else if ( out >= in2 )
+            out += d2;
+          else
+            out = out1 + FT_MulFix( out - in1, scale );
+
+          out_points[p].x = out;
+        }
+      }
+    }
+  }
+
+
+  /* Interpolate points without delta values, similar to */
+  /* the `IUP' hinting instruction.                      */
+
+  /* modeled after `Ins_IUP */
+
+  static void
+  tt_handle_deltas( FT_Outline*  outline,
+                    FT_Vector*   in_points,
+                    FT_Bool*     has_delta )
+  {
+    FT_Vector*  out_points;
+
+    FT_UInt  first_point;
+    FT_UInt  end_point;
+
+    FT_UInt  first_delta;
+    FT_UInt  cur_delta;
+
+    FT_UInt   point;
+    FT_Short  contour;
+
+
+    /* ignore empty outlines */
+    if ( !outline->n_contours )
+      return;
+
+    out_points = outline->points;
+
+    contour = 0;
+    point   = 0;
+
+    do
+    {
+      end_point   = outline->contours[contour];
+      first_point = point;
+
+      /* search first point that has a delta */
+      while ( point <= end_point && !has_delta[point] )
+        point++;
+
+      if ( point <= end_point )
+      {
+        first_delta = point;
+        cur_delta   = point;
+
+        point++;
+
+        while ( point <= end_point )
+        {
+          /* search next point that has a delta  */
+          /* and interpolate intermediate points */
+          if ( has_delta[point] )
+          {
+            tt_delta_interpolate( cur_delta + 1,
+                                  point - 1,
+                                  cur_delta,
+                                  point,
+                                  in_points,
+                                  out_points );
+            cur_delta = point;
+          }
+
+          point++;
+        }
+
+        /* shift contour if we only have a single delta */
+        if ( cur_delta == first_delta )
+          tt_delta_shift( first_point,
+                          end_point,
+                          cur_delta,
+                          in_points,
+                          out_points );
+        else
+        {
+          /* otherwise handle remaining points       */
+          /* at the end and beginning of the contour */
+          tt_delta_interpolate( cur_delta + 1,
+                                end_point,
+                                cur_delta,
+                                first_delta,
+                                in_points,
+                                out_points );
+
+          if ( first_delta > 0 )
+            tt_delta_interpolate( first_point,
+                                  first_delta - 1,
+                                  cur_delta,
+                                  first_delta,
+                                  in_points,
+                                  out_points );
+        }
+      }
+      contour++;
+
+    } while ( contour < outline->n_contours );
+  }
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    TT_Vary_Get_Glyph_Deltas                                           */
+  /*    TT_Vary_Apply_Glyph_Deltas                                         */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Load the appropriate deltas for the current glyph.                 */
+  /*    Apply the appropriate deltas to the current glyph.                 */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face        :: A handle to the target face object.                 */
@@ -1291,22 +1751,24 @@
   /*    n_points    :: The number of the points in the glyph, including    */
   /*                   phantom points.                                     */
   /*                                                                       */
-  /* <Output>                                                              */
-  /*    deltas      :: The array of points to change.                      */
+  /* <InOut>                                                               */
+  /*    outline     :: The outline to change.                              */
   /*                                                                       */
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
   FT_LOCAL_DEF( FT_Error )
-  TT_Vary_Get_Glyph_Deltas( TT_Face      face,
-                            FT_UInt      glyph_index,
-                            FT_Vector*  *deltas,
-                            FT_UInt      n_points )
+  TT_Vary_Apply_Glyph_Deltas( TT_Face      face,
+                              FT_UInt      glyph_index,
+                              FT_Outline*  outline,
+                              FT_UInt      n_points )
   {
     FT_Stream   stream = face->root.stream;
     FT_Memory   memory = stream->memory;
     GX_Blend    blend  = face->blend;
-    FT_Vector*  delta_xy = NULL;
+
+    FT_Vector*  points_org = NULL;
+    FT_Bool*    has_delta  = NULL;
 
     FT_Error    error;
     FT_ULong    glyph_start;
@@ -1327,15 +1789,18 @@
     if ( !face->doblend || blend == NULL )
       return FT_THROW( Invalid_Argument );
 
-    /* to be freed by the caller */
-    if ( FT_NEW_ARRAY( delta_xy, n_points ) )
-      goto Exit;
-    *deltas = delta_xy;
-
     if ( glyph_index >= blend->gv_glyphcnt      ||
          blend->glyphoffsets[glyph_index] ==
            blend->glyphoffsets[glyph_index + 1] )
-      return FT_Err_Ok;               /* no variation data for this glyph */
+    {
+      FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:"
+                  " no variation data for this glyph\n" ));
+      return FT_Err_Ok;
+    }
+
+    if ( FT_NEW_ARRAY( points_org, n_points ) ||
+         FT_NEW_ARRAY( has_delta, n_points )  )
+      goto Fail1;
 
     if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] )   ||
          FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] -
@@ -1367,40 +1832,42 @@
       FT_Stream_SeekSet( stream, here );
     }
 
-    for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); ++i )
+    FT_TRACE5(( "gvar: there are %d tuples:\n", tupleCount ));
+
+    for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ )
     {
       FT_UInt   tupleDataSize;
       FT_UInt   tupleIndex;
       FT_Fixed  apply;
 
 
+      FT_TRACE6(( "  tuple %d:\n", i ));
+
       tupleDataSize = FT_GET_USHORT();
       tupleIndex    = FT_GET_USHORT();
 
       if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
       {
-        for ( j = 0; j < blend->num_axis; ++j )
+        for ( j = 0; j < blend->num_axis; j++ )
           tuple_coords[j] = FT_GET_SHORT() << 2;  /* convert from        */
                                                   /* short frac to fixed */
       }
       else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
       {
         error = FT_THROW( Invalid_Table );
-        goto Fail3;
+        goto Fail2;
       }
       else
-      {
         FT_MEM_COPY(
           tuple_coords,
-          &blend->tuplecoords[(tupleIndex & 0xFFF) * blend->num_axis],
+          &blend->tuplecoords[( tupleIndex & 0xFFF ) * blend->num_axis],
           blend->num_axis * sizeof ( FT_Fixed ) );
-      }
 
       if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
       {
-        for ( j = 0; j < blend->num_axis; ++j )
+        for ( j = 0; j < blend->num_axis; j++ )
           im_start_coords[j] = FT_GET_SHORT() << 2;
-        for ( j = 0; j < blend->num_axis; ++j )
+        for ( j = 0; j < blend->num_axis; j++ )
           im_end_coords[j] = FT_GET_SHORT() << 2;
       }
 
@@ -1443,24 +1910,101 @@
 
       else if ( points == ALL_POINTS )
       {
+#ifdef FT_DEBUG_LEVEL_TRACE
+        int  count = 0;
+#endif
+
+
+        FT_TRACE7(( "    point deltas:\n" ));
+
         /* this means that there are deltas for every point in the glyph */
-        for ( j = 0; j < n_points; ++j )
+        for ( j = 0; j < n_points; j++ )
         {
-          delta_xy[j].x += FT_MulFix( deltas_x[j], apply );
-          delta_xy[j].y += FT_MulFix( deltas_y[j], apply );
+#ifdef FT_DEBUG_LEVEL_TRACE
+          FT_Vector  point_org = outline->points[j];
+#endif
+
+
+          outline->points[j].x += FT_MulFix( deltas_x[j], apply );
+          outline->points[j].y += FT_MulFix( deltas_y[j], apply );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+          if ( ( point_org.x != outline->points[j].x ) ||
+               ( point_org.y != outline->points[j].y ) )
+          {
+            FT_TRACE7(( "      %d: (%d, %d) -> (%d, %d)\n",
+                        j,
+                        point_org.x,
+                        point_org.y,
+                        outline->points[j].x,
+                        outline->points[j].y ));
+            count++;
+          }
+#endif
         }
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+        if ( !count )
+          FT_TRACE7(( "      none\n" ));
+#endif
       }
 
       else
       {
-        for ( j = 0; j < point_count; ++j )
+#ifdef FT_DEBUG_LEVEL_TRACE
+        int  count = 0;
+#endif
+
+
+        /* we have to interpolate the missing deltas similar to the */
+        /* IUP bytecode instruction                                 */
+        for ( j = 0; j < n_points; j++ )
         {
-          if ( localpoints[j] >= n_points )
+          points_org[j] = outline->points[j];
+          has_delta[j]  = FALSE;
+        }
+
+        for ( j = 0; j < point_count; j++ )
+        {
+          FT_UShort  idx = localpoints[j];
+
+
+          if ( idx >= n_points )
             continue;
 
-          delta_xy[localpoints[j]].x += FT_MulFix( deltas_x[j], apply );
-          delta_xy[localpoints[j]].y += FT_MulFix( deltas_y[j], apply );
+          has_delta[idx] = TRUE;
+
+          outline->points[idx].x += FT_MulFix( deltas_x[j], apply );
+          outline->points[idx].y += FT_MulFix( deltas_y[j], apply );
         }
+
+        /* no need to handle phantom points here,      */
+        /* since solitary points can't be interpolated */
+        tt_handle_deltas( outline,
+                          points_org,
+                          has_delta );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+        FT_TRACE7(( "    point deltas:\n" ));
+
+        for ( j = 0; j < n_points; j++)
+        {
+          if ( ( points_org[j].x != outline->points[j].x ) ||
+               ( points_org[j].y != outline->points[j].y ) )
+          {
+            FT_TRACE7(( "      %d: (%d, %d) -> (%d, %d)\n",
+                        j,
+                        points_org[j].x,
+                        points_org[j].y,
+                        outline->points[j].x,
+                        outline->points[j].y ));
+            count++;
+          }
+        }
+
+        if ( !count )
+          FT_TRACE7(( "      none\n" ));
+#endif
       }
 
       if ( localpoints != ALL_POINTS )
@@ -1473,22 +2017,19 @@
       FT_Stream_SeekSet( stream, here );
     }
 
-  Fail3:
+    FT_TRACE5(( "\n" ));
+
+  Fail2:
     FT_FREE( tuple_coords );
     FT_FREE( im_start_coords );
     FT_FREE( im_end_coords );
 
-  Fail2:
     FT_FRAME_EXIT();
 
   Fail1:
-    if ( error )
-    {
-      FT_FREE( delta_xy );
-      *deltas = NULL;
-    }
+    FT_FREE( points_org );
+    FT_FREE( has_delta );
 
-  Exit:
     return error;
   }
 
@@ -1499,7 +2040,7 @@
   /*    tt_done_blend                                                      */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Frees the blend internal data structure.                           */
+  /*    Free the blend internal data structure.                            */
   /*                                                                       */
   FT_LOCAL_DEF( void )
   tt_done_blend( FT_Memory  memory,
@@ -1515,7 +2056,7 @@
 
       if ( blend->avar_segment != NULL )
       {
-        for ( i = 0; i < blend->num_axis; ++i )
+        for ( i = 0; i < blend->num_axis; i++ )
           FT_FREE( blend->avar_segment[i].correspondence );
         FT_FREE( blend->avar_segment );
       }
diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h
index 82dfc44..060d4d6 100644
--- a/src/truetype/ttgxvar.h
+++ b/src/truetype/ttgxvar.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType GX Font Variation loader (specification)                    */
 /*                                                                         */
-/*  Copyright 2004 by                                                      */
+/*  Copyright 2004-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, Werner Lemberg and George Williams.      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -162,10 +162,10 @@
 
 
   FT_LOCAL( FT_Error )
-  TT_Vary_Get_Glyph_Deltas( TT_Face      face,
-                            FT_UInt      glyph_index,
-                            FT_Vector*  *deltas,
-                            FT_UInt      n_points );
+  TT_Vary_Apply_Glyph_Deltas( TT_Face      face,
+                              FT_UInt      glyph_index,
+                              FT_Outline*  outline,
+                              FT_UInt      n_points );
 
 
   FT_LOCAL( void )
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index 9491533..089f604 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -4,8 +4,8 @@
 /*                                                                         */
 /*    TrueType bytecode interpreter (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2014                                                    */
-/*  by David Turner, Robert Wilhelm, and Werner Lemberg.                   */
+/*  Copyright 1996-2015 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      */
@@ -44,6 +44,7 @@
 #undef  FT_COMPONENT
 #define FT_COMPONENT  trace_ttinterp
 
+
   /*************************************************************************/
   /*                                                                       */
   /* In order to detect infinite loops in the code, we set up a counter    */
@@ -53,177 +54,30 @@
 #define MAX_RUNNABLE_OPCODES  1000000L
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* There are two kinds of implementations:                               */
-  /*                                                                       */
-  /* a. static implementation                                              */
-  /*                                                                       */
-  /*    The current execution context is a static variable, which fields   */
-  /*    are accessed directly by the interpreter during execution.  The    */
-  /*    context is named `cur'.                                            */
-  /*                                                                       */
-  /*    This version is non-reentrant, of course.                          */
-  /*                                                                       */
-  /* b. indirect implementation                                            */
-  /*                                                                       */
-  /*    The current execution context is passed to _each_ function as its  */
-  /*    first argument, and each field is thus accessed indirectly.        */
-  /*                                                                       */
-  /*    This version is fully re-entrant.                                  */
-  /*                                                                       */
-  /* The idea is that an indirect implementation may be slower to execute  */
-  /* on low-end processors that are used in some systems (like 386s or     */
-  /* even 486s).                                                           */
-  /*                                                                       */
-  /* As a consequence, the indirect implementation is now the default, as  */
-  /* its performance costs can be considered negligible in our context.    */
-  /* Note, however, that we kept the same source with macros because:      */
-  /*                                                                       */
-  /* - The code is kept very close in design to the Pascal code used for   */
-  /*   development.                                                        */
-  /*                                                                       */
-  /* - It's much more readable that way!                                   */
-  /*                                                                       */
-  /* - It's still open to experimentation and tuning.                      */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER     /* indirect implementation */
-
-#define CUR  (*exc)                             /* see ttobjs.h */
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* This macro is used whenever `exec' is unused in a function, to avoid  */
-  /* stupid warnings from pedantic compilers.                              */
-  /*                                                                       */
-#define FT_UNUSED_EXEC  FT_UNUSED( exc )
-
-#else                                           /* static implementation */
-
-#define CUR  cur
-
-#define FT_UNUSED_EXEC  int  __dummy = __dummy
-
-  static
-  TT_ExecContextRec  cur;   /* static exec. context variable */
-
-  /* apparently, we have a _lot_ of direct indexing when accessing  */
-  /* the static `cur', which makes the code bigger (due to all the  */
-  /* four bytes addresses).                                         */
-
-#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The instruction argument stack.                                       */
-  /*                                                                       */
-#define INS_ARG  EXEC_OP_ FT_Long*  args    /* see ttobjs.h for EXEC_OP_ */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* This macro is used whenever `args' is unused in a function, to avoid  */
-  /* stupid warnings from pedantic compilers.                              */
-  /*                                                                       */
-#define FT_UNUSED_ARG  FT_UNUSED_EXEC; FT_UNUSED( args )
-
-
-#define SUBPIXEL_HINTING                                                    \
-          ( ((TT_Driver)FT_FACE_DRIVER( CUR.face ))->interpreter_version == \
+#define SUBPIXEL_HINTING                                                     \
+          ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
             TT_INTERPRETER_VERSION_38 )
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to        */
-  /* increase readability of the code.                                     */
-  /*                                                                       */
-  /*************************************************************************/
+#define PROJECT( v1, v2 )                                                \
+          exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
 
+#define DUALPROJ( v1, v2 )                                                \
+          exc->func_dualproj( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y )
 
-#define SKIP_Code() \
-          SkipCode( EXEC_ARG )
+#define FAST_PROJECT( v )                          \
+          exc->func_project( exc, (v)->x, (v)->y )
 
-#define GET_ShortIns() \
-          GetShortIns( EXEC_ARG )
-
-#define NORMalize( x, y, v ) \
-          Normalize( EXEC_ARG_ x, y, v )
-
-#define SET_SuperRound( scale, flags ) \
-          SetSuperRound( EXEC_ARG_ scale, flags )
-
-#define ROUND_None( d, c ) \
-          Round_None( EXEC_ARG_ d, c )
-
-#define INS_Goto_CodeRange( range, ip ) \
-          Ins_Goto_CodeRange( EXEC_ARG_ range, ip )
-
-#define CUR_Func_move( z, p, d ) \
-          CUR.func_move( EXEC_ARG_ z, p, d )
-
-#define CUR_Func_move_orig( z, p, d ) \
-          CUR.func_move_orig( EXEC_ARG_ z, p, d )
-
-#define CUR_Func_round( d, c ) \
-          CUR.func_round( EXEC_ARG_ d, c )
-
-#define CUR_Func_read_cvt( index ) \
-          CUR.func_read_cvt( EXEC_ARG_ index )
-
-#define CUR_Func_write_cvt( index, val ) \
-          CUR.func_write_cvt( EXEC_ARG_ index, val )
-
-#define CUR_Func_move_cvt( index, val ) \
-          CUR.func_move_cvt( EXEC_ARG_ index, val )
-
-#define CURRENT_Ratio() \
-          Current_Ratio( EXEC_ARG )
-
-#define CURRENT_Ppem() \
-          Current_Ppem( EXEC_ARG )
-
-#define CUR_Ppem() \
-          Cur_PPEM( EXEC_ARG )
-
-#define INS_SxVTL( a, b, c, d ) \
-          Ins_SxVTL( EXEC_ARG_ a, b, c, d )
-
-#define COMPUTE_Funcs() \
-          Compute_Funcs( EXEC_ARG )
-
-#define COMPUTE_Round( a ) \
-          Compute_Round( EXEC_ARG_ a )
-
-#define COMPUTE_Point_Displacement( a, b, c, d ) \
-          Compute_Point_Displacement( EXEC_ARG_ a, b, c, d )
-
-#define MOVE_Zp2_Point( a, b, c, t ) \
-          Move_Zp2_Point( EXEC_ARG_ a, b, c, t )
-
-
-#define CUR_Func_project( v1, v2 )  \
-          CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
-
-#define CUR_Func_dualproj( v1, v2 )  \
-          CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
-
-#define CUR_fast_project( v ) \
-          CUR.func_project( EXEC_ARG_ (v)->x, (v)->y )
-
-#define CUR_fast_dualproj( v ) \
-          CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y )
+#define FAST_DUALPROJ( v )                          \
+          exc->func_dualproj( exc, (v)->x, (v)->y )
 
 
   /*************************************************************************/
   /*                                                                       */
   /* Instruction dispatch function, as used by the interpreter.            */
   /*                                                                       */
-  typedef void  (*TInstruction_Function)( INS_ARG );
+  typedef void  (*TInstruction_Function)( TT_ExecContext  exc,
+                                          FT_Long*        args );
 
 
   /*************************************************************************/
@@ -233,12 +87,12 @@
 #define BOUNDS( x, n )   ( (FT_UInt)(x)  >= (FT_UInt)(n)  )
 #define BOUNDSL( x, n )  ( (FT_ULong)(x) >= (FT_ULong)(n) )
 
+
   /*************************************************************************/
   /*                                                                       */
   /* This macro computes (a*2^14)/b and complements TT_MulFix14.           */
   /*                                                                       */
-#define TT_DivFix14( a, b ) \
-          FT_DivFix( a, (b) << 2 )
+#define TT_DivFix14( a, b )  FT_DivFix( a, (b) << 2 )
 
 
 #undef  SUCCESS
@@ -248,16 +102,20 @@
 #define FAILURE  1
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-#define GUESS_VECTOR( V )                                         \
-  if ( CUR.face->unpatented_hinting )                             \
-  {                                                               \
-    CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \
-    CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \
-  }
+#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 )
+#define GUESS_VECTOR( V )  do { } while (0)
 #endif
 
+
   /*************************************************************************/
   /*                                                                       */
   /*                        CODERANGE FUNCTIONS                            */
@@ -282,10 +140,7 @@
   /* <InOut>                                                               */
   /*    exec  :: The target execution context.                             */
   /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  FT_LOCAL_DEF( FT_Error )
+  FT_LOCAL_DEF( void )
   TT_Goto_CodeRange( TT_ExecContext  exec,
                      FT_Int          range,
                      FT_Long         IP )
@@ -303,14 +158,12 @@
     /*       which will return to the first byte *after* the code    */
     /*       range, we test for IP <= Size instead of IP < Size.     */
     /*                                                               */
-    FT_ASSERT( (FT_ULong)IP <= coderange->size );
+    FT_ASSERT( IP <= coderange->size );
 
     exec->code     = coderange->base;
     exec->codeSize = coderange->size;
     exec->IP       = IP;
     exec->curRange = range;
-
-    return FT_Err_Ok;
   }
 
 
@@ -332,10 +185,7 @@
   /* <InOut>                                                               */
   /*    exec   :: The target execution context.                            */
   /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  FT_LOCAL_DEF( FT_Error )
+  FT_LOCAL_DEF( void )
   TT_Set_CodeRange( TT_ExecContext  exec,
                     FT_Int          range,
                     void*           base,
@@ -345,8 +195,6 @@
 
     exec->codeRangeTable[range - 1].base = (FT_Byte*)base;
     exec->codeRangeTable[range - 1].size = length;
-
-    return FT_Err_Ok;
   }
 
 
@@ -364,13 +212,7 @@
   /* <InOut>                                                               */
   /*    exec  :: The target execution context.                             */
   /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    Does not set the Error variable.                                   */
-  /*                                                                       */
-  FT_LOCAL_DEF( FT_Error )
+  FT_LOCAL_DEF( void )
   TT_Clear_CodeRange( TT_ExecContext  exec,
                       FT_Int          range )
   {
@@ -378,8 +220,6 @@
 
     exec->codeRangeTable[range - 1].base = NULL;
     exec->codeRangeTable[range - 1].size = 0;
-
-    return FT_Err_Ok;
   }
 
 
@@ -403,13 +243,10 @@
   /*                                                                       */
   /*    memory :: A handle to the parent memory object.                    */
   /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
   /* <Note>                                                                */
   /*    Only the glyph loader and debugger should call this function.      */
   /*                                                                       */
-  FT_LOCAL_DEF( FT_Error )
+  FT_LOCAL_DEF( void )
   TT_Done_Context( TT_ExecContext  exec )
   {
     FT_Memory  memory = exec->memory;
@@ -436,8 +273,6 @@
     exec->face = NULL;
 
     FT_FREE( exec );
-
-    return FT_Err_Ok;
   }
 
 
@@ -524,7 +359,7 @@
   FT_LOCAL_DEF( FT_Error )
   Update_Max( FT_Memory  memory,
               FT_ULong*  size,
-              FT_Long    multiplier,
+              FT_ULong   multiplier,
               void*      _pbuff,
               FT_ULong   new_max )
   {
@@ -617,13 +452,13 @@
 
     /* XXX: We reserve a little more elements on the stack to deal safely */
     /*      with broken fonts like arialbs, courbs, timesbs, etc.         */
-    tmp = exec->stackSize;
+    tmp = (FT_ULong)exec->stackSize;
     error = Update_Max( exec->memory,
                         &tmp,
                         sizeof ( FT_F26Dot6 ),
                         (void*)&exec->stack,
                         maxp->maxStackElements + 32 );
-    exec->stackSize = (FT_UInt)tmp;
+    exec->stackSize = (FT_Long)tmp;
     if ( error )
       return error;
 
@@ -664,13 +499,10 @@
   /* <InOut>                                                               */
   /*    size :: A handle to the target size object.                        */
   /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
   /* <Note>                                                                */
   /*    Only the glyph loader and debugger should call this function.      */
   /*                                                                       */
-  FT_LOCAL_DEF( FT_Error )
+  FT_LOCAL_DEF( void )
   TT_Save_Context( TT_ExecContext  exec,
                    TT_Size         size )
   {
@@ -688,8 +520,6 @@
 
     for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
       size->codeRangeTable[i] = exec->codeRangeTable[i];
-
-    return FT_Err_Ok;
   }
 
 
@@ -714,19 +544,10 @@
   /* <Return>                                                              */
   /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
-  /* <Note>                                                                */
-  /*    Only the glyph loader and debugger should call this function.      */
-  /*                                                                       */
   FT_LOCAL_DEF( FT_Error )
-  TT_Run_Context( TT_ExecContext  exec,
-                  FT_Bool         debug )
+  TT_Run_Context( TT_ExecContext  exec )
   {
-    FT_Error  error;
-
-
-    if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) )
-           != FT_Err_Ok )
-      return error;
+    TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 );
 
     exec->zp0 = exec->pts;
     exec->zp1 = exec->pts;
@@ -754,16 +575,7 @@
     exec->top     = 0;
     exec->callTop = 0;
 
-#if 1
-    FT_UNUSED( debug );
-
     return exec->face->interpreter( exec );
-#else
-    if ( !debug )
-      return TT_RunIns( exec );
-    else
-      return FT_Err_Ok;
-#endif
   }
 
 
@@ -796,29 +608,27 @@
   FT_EXPORT_DEF( TT_ExecContext )
   TT_New_Context( TT_Driver  driver )
   {
-    FT_Memory  memory = driver->root.root.memory;
+    FT_Memory  memory;
+    FT_Error   error;
+
+    TT_ExecContext  exec = NULL;
 
 
-    if ( !driver->context )
-    {
-      FT_Error        error;
-      TT_ExecContext  exec;
+    if ( !driver )
+      goto Fail;
 
+    memory = driver->root.root.memory;
 
-      /* allocate object */
-      if ( FT_NEW( exec ) )
-        goto Fail;
+    /* allocate object */
+    if ( FT_NEW( exec ) )
+      goto Fail;
 
-      /* initialize it; in case of error this deallocates `exec' too */
-      error = Init_Context( exec, memory );
-      if ( error )
-        goto Fail;
+    /* initialize it; in case of error this deallocates `exec' too */
+    error = Init_Context( exec, memory );
+    if ( error )
+      goto Fail;
 
-      /* store it into the driver */
-      driver->context = exec;
-    }
-
-    return driver->context;
+    return exec;
 
   Fail:
     return NULL;
@@ -865,8 +675,8 @@
     /*  SFvTL +   */  PACK( 2, 0 ),
     /*  SPvFS     */  PACK( 2, 0 ),
     /*  SFvFS     */  PACK( 2, 0 ),
-    /*  GPV       */  PACK( 0, 2 ),
-    /*  GFV       */  PACK( 0, 2 ),
+    /*  GPv       */  PACK( 0, 2 ),
+    /*  GFv       */  PACK( 0, 2 ),
     /*  SFvTPv    */  PACK( 0, 0 ),
     /*  ISECT     */  PACK( 5, 0 ),
 
@@ -995,8 +805,8 @@
     /*  INS_$83   */  PACK( 0, 0 ),
     /*  INS_$84   */  PACK( 0, 0 ),
     /*  ScanCTRL  */  PACK( 1, 0 ),
-    /*  SDPVTL[0] */  PACK( 2, 0 ),
-    /*  SDPVTL[1] */  PACK( 2, 0 ),
+    /*  SDPvTL[0] */  PACK( 2, 0 ),
+    /*  SDPvTL[1] */  PACK( 2, 0 ),
     /*  GetINFO   */  PACK( 1, 1 ),
     /*  IDEF      */  PACK( 1, 0 ),
     /*  ROLL      */  PACK( 3, 3 ),
@@ -1129,280 +939,284 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
 
+  /* the first hex digit gives the length of the opcode name; the space */
+  /* after the digit is here just to increase readability of the source */
+  /* code                                                               */
+
   static
   const char*  const opcode_name[256] =
   {
-    "SVTCA y",
-    "SVTCA x",
-    "SPvTCA y",
-    "SPvTCA x",
-    "SFvTCA y",
-    "SFvTCA x",
-    "SPvTL ||",
-    "SPvTL +",
-    "SFvTL ||",
-    "SFvTL +",
-    "SPvFS",
-    "SFvFS",
-    "GPV",
-    "GFV",
-    "SFvTPv",
-    "ISECT",
+    "7 SVTCA y",
+    "7 SVTCA x",
+    "8 SPvTCA y",
+    "8 SPvTCA x",
+    "8 SFvTCA y",
+    "8 SFvTCA x",
+    "8 SPvTL ||",
+    "7 SPvTL +",
+    "8 SFvTL ||",
+    "7 SFvTL +",
+    "5 SPvFS",
+    "5 SFvFS",
+    "3 GPv",
+    "3 GFv",
+    "6 SFvTPv",
+    "5 ISECT",
 
-    "SRP0",
-    "SRP1",
-    "SRP2",
-    "SZP0",
-    "SZP1",
-    "SZP2",
-    "SZPS",
-    "SLOOP",
-    "RTG",
-    "RTHG",
-    "SMD",
-    "ELSE",
-    "JMPR",
-    "SCvTCi",
-    "SSwCi",
-    "SSW",
+    "4 SRP0",
+    "4 SRP1",
+    "4 SRP2",
+    "4 SZP0",
+    "4 SZP1",
+    "4 SZP2",
+    "4 SZPS",
+    "5 SLOOP",
+    "3 RTG",
+    "4 RTHG",
+    "3 SMD",
+    "4 ELSE",
+    "4 JMPR",
+    "6 SCvTCi",
+    "5 SSwCi",
+    "3 SSW",
 
-    "DUP",
-    "POP",
-    "CLEAR",
-    "SWAP",
-    "DEPTH",
-    "CINDEX",
-    "MINDEX",
-    "AlignPTS",
-    "INS_$28",
-    "UTP",
-    "LOOPCALL",
-    "CALL",
-    "FDEF",
-    "ENDF",
-    "MDAP[0]",
-    "MDAP[1]",
+    "3 DUP",
+    "3 POP",
+    "5 CLEAR",
+    "4 SWAP",
+    "5 DEPTH",
+    "6 CINDEX",
+    "6 MINDEX",
+    "8 AlignPTS",
+    "7 INS_$28",
+    "3 UTP",
+    "8 LOOPCALL",
+    "4 CALL",
+    "4 FDEF",
+    "4 ENDF",
+    "7 MDAP[0]",
+    "7 MDAP[1]",
 
-    "IUP[0]",
-    "IUP[1]",
-    "SHP[0]",
-    "SHP[1]",
-    "SHC[0]",
-    "SHC[1]",
-    "SHZ[0]",
-    "SHZ[1]",
-    "SHPIX",
-    "IP",
-    "MSIRP[0]",
-    "MSIRP[1]",
-    "AlignRP",
-    "RTDG",
-    "MIAP[0]",
-    "MIAP[1]",
+    "6 IUP[0]",
+    "6 IUP[1]",
+    "6 SHP[0]",
+    "6 SHP[1]",
+    "6 SHC[0]",
+    "6 SHC[1]",
+    "6 SHZ[0]",
+    "6 SHZ[1]",
+    "5 SHPIX",
+    "2 IP",
+    "8 MSIRP[0]",
+    "8 MSIRP[1]",
+    "7 AlignRP",
+    "4 RTDG",
+    "7 MIAP[0]",
+    "7 MIAP[1]",
 
-    "NPushB",
-    "NPushW",
-    "WS",
-    "RS",
-    "WCvtP",
-    "RCvt",
-    "GC[0]",
-    "GC[1]",
-    "SCFS",
-    "MD[0]",
-    "MD[1]",
-    "MPPEM",
-    "MPS",
-    "FlipON",
-    "FlipOFF",
-    "DEBUG",
+    "6 NPushB",
+    "6 NPushW",
+    "2 WS",
+    "2 RS",
+    "5 WCvtP",
+    "4 RCvt",
+    "5 GC[0]",
+    "5 GC[1]",
+    "4 SCFS",
+    "5 MD[0]",
+    "5 MD[1]",
+    "5 MPPEM",
+    "3 MPS",
+    "6 FlipON",
+    "7 FlipOFF",
+    "5 DEBUG",
 
-    "LT",
-    "LTEQ",
-    "GT",
-    "GTEQ",
-    "EQ",
-    "NEQ",
-    "ODD",
-    "EVEN",
-    "IF",
-    "EIF",
-    "AND",
-    "OR",
-    "NOT",
-    "DeltaP1",
-    "SDB",
-    "SDS",
+    "2 LT",
+    "4 LTEQ",
+    "2 GT",
+    "4 GTEQ",
+    "2 EQ",
+    "3 NEQ",
+    "3 ODD",
+    "4 EVEN",
+    "2 IF",
+    "3 EIF",
+    "3 AND",
+    "2 OR",
+    "3 NOT",
+    "7 DeltaP1",
+    "3 SDB",
+    "3 SDS",
 
-    "ADD",
-    "SUB",
-    "DIV",
-    "MUL",
-    "ABS",
-    "NEG",
-    "FLOOR",
-    "CEILING",
-    "ROUND[0]",
-    "ROUND[1]",
-    "ROUND[2]",
-    "ROUND[3]",
-    "NROUND[0]",
-    "NROUND[1]",
-    "NROUND[2]",
-    "NROUND[3]",
+    "3 ADD",
+    "3 SUB",
+    "3 DIV",
+    "3 MUL",
+    "3 ABS",
+    "3 NEG",
+    "5 FLOOR",
+    "7 CEILING",
+    "8 ROUND[0]",
+    "8 ROUND[1]",
+    "8 ROUND[2]",
+    "8 ROUND[3]",
+    "9 NROUND[0]",
+    "9 NROUND[1]",
+    "9 NROUND[2]",
+    "9 NROUND[3]",
 
-    "WCvtF",
-    "DeltaP2",
-    "DeltaP3",
-    "DeltaCn[0]",
-    "DeltaCn[1]",
-    "DeltaCn[2]",
-    "SROUND",
-    "S45Round",
-    "JROT",
-    "JROF",
-    "ROFF",
-    "INS_$7B",
-    "RUTG",
-    "RDTG",
-    "SANGW",
-    "AA",
+    "5 WCvtF",
+    "7 DeltaP2",
+    "7 DeltaP3",
+    "A DeltaCn[0]",
+    "A DeltaCn[1]",
+    "A DeltaCn[2]",
+    "6 SROUND",
+    "8 S45Round",
+    "4 JROT",
+    "4 JROF",
+    "4 ROFF",
+    "7 INS_$7B",
+    "4 RUTG",
+    "4 RDTG",
+    "5 SANGW",
+    "2 AA",
 
-    "FlipPT",
-    "FlipRgON",
-    "FlipRgOFF",
-    "INS_$83",
-    "INS_$84",
-    "ScanCTRL",
-    "SDVPTL[0]",
-    "SDVPTL[1]",
-    "GetINFO",
-    "IDEF",
-    "ROLL",
-    "MAX",
-    "MIN",
-    "ScanTYPE",
-    "InstCTRL",
-    "INS_$8F",
+    "6 FlipPT",
+    "8 FlipRgON",
+    "9 FlipRgOFF",
+    "7 INS_$83",
+    "7 INS_$84",
+    "8 ScanCTRL",
+    "9 SDPvTL[0]",
+    "9 SDPvTL[1]",
+    "7 GetINFO",
+    "4 IDEF",
+    "4 ROLL",
+    "3 MAX",
+    "3 MIN",
+    "8 ScanTYPE",
+    "8 InstCTRL",
+    "7 INS_$8F",
 
-    "INS_$90",
-    "INS_$91",
-    "INS_$92",
-    "INS_$93",
-    "INS_$94",
-    "INS_$95",
-    "INS_$96",
-    "INS_$97",
-    "INS_$98",
-    "INS_$99",
-    "INS_$9A",
-    "INS_$9B",
-    "INS_$9C",
-    "INS_$9D",
-    "INS_$9E",
-    "INS_$9F",
+    "7 INS_$90",
+    "7 INS_$91",
+    "7 INS_$92",
+    "7 INS_$93",
+    "7 INS_$94",
+    "7 INS_$95",
+    "7 INS_$96",
+    "7 INS_$97",
+    "7 INS_$98",
+    "7 INS_$99",
+    "7 INS_$9A",
+    "7 INS_$9B",
+    "7 INS_$9C",
+    "7 INS_$9D",
+    "7 INS_$9E",
+    "7 INS_$9F",
 
-    "INS_$A0",
-    "INS_$A1",
-    "INS_$A2",
-    "INS_$A3",
-    "INS_$A4",
-    "INS_$A5",
-    "INS_$A6",
-    "INS_$A7",
-    "INS_$A8",
-    "INS_$A9",
-    "INS_$AA",
-    "INS_$AB",
-    "INS_$AC",
-    "INS_$AD",
-    "INS_$AE",
-    "INS_$AF",
+    "7 INS_$A0",
+    "7 INS_$A1",
+    "7 INS_$A2",
+    "7 INS_$A3",
+    "7 INS_$A4",
+    "7 INS_$A5",
+    "7 INS_$A6",
+    "7 INS_$A7",
+    "7 INS_$A8",
+    "7 INS_$A9",
+    "7 INS_$AA",
+    "7 INS_$AB",
+    "7 INS_$AC",
+    "7 INS_$AD",
+    "7 INS_$AE",
+    "7 INS_$AF",
 
-    "PushB[0]",
-    "PushB[1]",
-    "PushB[2]",
-    "PushB[3]",
-    "PushB[4]",
-    "PushB[5]",
-    "PushB[6]",
-    "PushB[7]",
-    "PushW[0]",
-    "PushW[1]",
-    "PushW[2]",
-    "PushW[3]",
-    "PushW[4]",
-    "PushW[5]",
-    "PushW[6]",
-    "PushW[7]",
+    "8 PushB[0]",
+    "8 PushB[1]",
+    "8 PushB[2]",
+    "8 PushB[3]",
+    "8 PushB[4]",
+    "8 PushB[5]",
+    "8 PushB[6]",
+    "8 PushB[7]",
+    "8 PushW[0]",
+    "8 PushW[1]",
+    "8 PushW[2]",
+    "8 PushW[3]",
+    "8 PushW[4]",
+    "8 PushW[5]",
+    "8 PushW[6]",
+    "8 PushW[7]",
 
-    "MDRP[00]",
-    "MDRP[01]",
-    "MDRP[02]",
-    "MDRP[03]",
-    "MDRP[04]",
-    "MDRP[05]",
-    "MDRP[06]",
-    "MDRP[07]",
-    "MDRP[08]",
-    "MDRP[09]",
-    "MDRP[10]",
-    "MDRP[11]",
-    "MDRP[12]",
-    "MDRP[13]",
-    "MDRP[14]",
-    "MDRP[15]",
+    "8 MDRP[00]",
+    "8 MDRP[01]",
+    "8 MDRP[02]",
+    "8 MDRP[03]",
+    "8 MDRP[04]",
+    "8 MDRP[05]",
+    "8 MDRP[06]",
+    "8 MDRP[07]",
+    "8 MDRP[08]",
+    "8 MDRP[09]",
+    "8 MDRP[10]",
+    "8 MDRP[11]",
+    "8 MDRP[12]",
+    "8 MDRP[13]",
+    "8 MDRP[14]",
+    "8 MDRP[15]",
 
-    "MDRP[16]",
-    "MDRP[17]",
-    "MDRP[18]",
-    "MDRP[19]",
-    "MDRP[20]",
-    "MDRP[21]",
-    "MDRP[22]",
-    "MDRP[23]",
-    "MDRP[24]",
-    "MDRP[25]",
-    "MDRP[26]",
-    "MDRP[27]",
-    "MDRP[28]",
-    "MDRP[29]",
-    "MDRP[30]",
-    "MDRP[31]",
+    "8 MDRP[16]",
+    "8 MDRP[17]",
+    "8 MDRP[18]",
+    "8 MDRP[19]",
+    "8 MDRP[20]",
+    "8 MDRP[21]",
+    "8 MDRP[22]",
+    "8 MDRP[23]",
+    "8 MDRP[24]",
+    "8 MDRP[25]",
+    "8 MDRP[26]",
+    "8 MDRP[27]",
+    "8 MDRP[28]",
+    "8 MDRP[29]",
+    "8 MDRP[30]",
+    "8 MDRP[31]",
 
-    "MIRP[00]",
-    "MIRP[01]",
-    "MIRP[02]",
-    "MIRP[03]",
-    "MIRP[04]",
-    "MIRP[05]",
-    "MIRP[06]",
-    "MIRP[07]",
-    "MIRP[08]",
-    "MIRP[09]",
-    "MIRP[10]",
-    "MIRP[11]",
-    "MIRP[12]",
-    "MIRP[13]",
-    "MIRP[14]",
-    "MIRP[15]",
+    "8 MIRP[00]",
+    "8 MIRP[01]",
+    "8 MIRP[02]",
+    "8 MIRP[03]",
+    "8 MIRP[04]",
+    "8 MIRP[05]",
+    "8 MIRP[06]",
+    "8 MIRP[07]",
+    "8 MIRP[08]",
+    "8 MIRP[09]",
+    "8 MIRP[10]",
+    "8 MIRP[11]",
+    "8 MIRP[12]",
+    "8 MIRP[13]",
+    "8 MIRP[14]",
+    "8 MIRP[15]",
 
-    "MIRP[16]",
-    "MIRP[17]",
-    "MIRP[18]",
-    "MIRP[19]",
-    "MIRP[20]",
-    "MIRP[21]",
-    "MIRP[22]",
-    "MIRP[23]",
-    "MIRP[24]",
-    "MIRP[25]",
-    "MIRP[26]",
-    "MIRP[27]",
-    "MIRP[28]",
-    "MIRP[29]",
-    "MIRP[30]",
-    "MIRP[31]"
+    "8 MIRP[16]",
+    "8 MIRP[17]",
+    "8 MIRP[18]",
+    "8 MIRP[19]",
+    "8 MIRP[20]",
+    "8 MIRP[21]",
+    "8 MIRP[22]",
+    "8 MIRP[23]",
+    "8 MIRP[24]",
+    "8 MIRP[25]",
+    "8 MIRP[26]",
+    "8 MIRP[27]",
+    "8 MIRP[28]",
+    "8 MIRP[29]",
+    "8 MIRP[30]",
+    "8 MIRP[31]"
   };
 
 #endif /* FT_DEBUG_LEVEL_TRACE */
@@ -1446,7 +1260,7 @@
   TT_MulFix14_arm( FT_Int32  a,
                    FT_Int    b )
   {
-    register FT_Int32  t, t2;
+    FT_Int32  t, t2;
 
 
 #if defined( __CC_ARM ) || defined( __ARMCC__ )
@@ -1668,48 +1482,55 @@
   /*    The aspect ratio in 16.16 format, always <= 1.0 .                  */
   /*                                                                       */
   static FT_Long
-  Current_Ratio( EXEC_OP )
+  Current_Ratio( TT_ExecContext  exc )
   {
-    if ( !CUR.tt_metrics.ratio )
+    if ( !exc->tt_metrics.ratio )
     {
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-      if ( CUR.face->unpatented_hinting )
+      if ( exc->face->unpatented_hinting )
       {
-        if ( CUR.GS.both_x_axis )
-          CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
+        if ( exc->GS.both_x_axis )
+          exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
         else
-          CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
+          exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
       }
       else
 #endif
       {
-        if ( CUR.GS.projVector.y == 0 )
-          CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
+        if ( exc->GS.projVector.y == 0 )
+          exc->tt_metrics.ratio = exc->tt_metrics.x_ratio;
 
-        else if ( CUR.GS.projVector.x == 0 )
-          CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
+        else if ( exc->GS.projVector.x == 0 )
+          exc->tt_metrics.ratio = exc->tt_metrics.y_ratio;
 
         else
         {
           FT_F26Dot6  x, y;
 
 
-          x = TT_MulFix14( CUR.tt_metrics.x_ratio,
-                           CUR.GS.projVector.x );
-          y = TT_MulFix14( CUR.tt_metrics.y_ratio,
-                           CUR.GS.projVector.y );
-          CUR.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 CUR.tt_metrics.ratio;
+    return exc->tt_metrics.ratio;
   }
 
 
-  static FT_Long
-  Current_Ppem( EXEC_OP )
+  FT_CALLBACK_DEF( FT_Long )
+  Current_Ppem( TT_ExecContext  exc )
   {
-    return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() );
+    return exc->tt_metrics.ppem;
+  }
+
+
+  FT_CALLBACK_DEF( FT_Long )
+  Current_Ppem_Stretched( TT_ExecContext  exc )
+  {
+    return FT_MulFix( exc->tt_metrics.ppem, Current_Ratio( exc ) );
   }
 
 
@@ -1721,48 +1542,54 @@
 
 
   FT_CALLBACK_DEF( FT_F26Dot6 )
-  Read_CVT( EXEC_OP_ FT_ULong  idx )
+  Read_CVT( TT_ExecContext  exc,
+            FT_ULong        idx )
   {
-    return CUR.cvt[idx];
+    return exc->cvt[idx];
   }
 
 
   FT_CALLBACK_DEF( FT_F26Dot6 )
-  Read_CVT_Stretched( EXEC_OP_ FT_ULong  idx )
+  Read_CVT_Stretched( TT_ExecContext  exc,
+                      FT_ULong        idx )
   {
-    return FT_MulFix( CUR.cvt[idx], CURRENT_Ratio() );
+    return FT_MulFix( exc->cvt[idx], Current_Ratio( exc ) );
   }
 
 
   FT_CALLBACK_DEF( void )
-  Write_CVT( EXEC_OP_ FT_ULong    idx,
-                      FT_F26Dot6  value )
+  Write_CVT( TT_ExecContext  exc,
+             FT_ULong        idx,
+             FT_F26Dot6      value )
   {
-    CUR.cvt[idx] = value;
+    exc->cvt[idx] = value;
   }
 
 
   FT_CALLBACK_DEF( void )
-  Write_CVT_Stretched( EXEC_OP_ FT_ULong    idx,
-                                FT_F26Dot6  value )
+  Write_CVT_Stretched( TT_ExecContext  exc,
+                       FT_ULong        idx,
+                       FT_F26Dot6      value )
   {
-    CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() );
+    exc->cvt[idx] = FT_DivFix( value, Current_Ratio( exc ) );
   }
 
 
   FT_CALLBACK_DEF( void )
-  Move_CVT( EXEC_OP_ FT_ULong    idx,
-                     FT_F26Dot6  value )
+  Move_CVT( TT_ExecContext  exc,
+            FT_ULong        idx,
+            FT_F26Dot6      value )
   {
-    CUR.cvt[idx] += value;
+    exc->cvt[idx] += value;
   }
 
 
   FT_CALLBACK_DEF( void )
-  Move_CVT_Stretched( EXEC_OP_ FT_ULong    idx,
-                               FT_F26Dot6  value )
+  Move_CVT_Stretched( TT_ExecContext  exc,
+                      FT_ULong        idx,
+                      FT_F26Dot6      value )
   {
-    CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() );
+    exc->cvt[idx] += FT_DivFix( value, Current_Ratio( exc ) );
   }
 
 
@@ -1782,12 +1609,12 @@
   /*    This one could become a macro.                                     */
   /*                                                                       */
   static FT_Short
-  GetShortIns( EXEC_OP )
+  GetShortIns( TT_ExecContext  exc )
   {
     /* Reading a byte stream so there is no endianess (DaveP) */
-    CUR.IP += 2;
-    return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) +
-                         CUR.code[CUR.IP - 1]      );
+    exc->IP += 2;
+    return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) +
+                         exc->code[exc->IP - 1]      );
   }
 
 
@@ -1808,23 +1635,24 @@
   /*    SUCCESS or FAILURE.                                                */
   /*                                                                       */
   static FT_Bool
-  Ins_Goto_CodeRange( EXEC_OP_ FT_Int    aRange,
-                               FT_ULong  aIP )
+  Ins_Goto_CodeRange( TT_ExecContext  exc,
+                      FT_Int          aRange,
+                      FT_Long         aIP )
   {
     TT_CodeRange*  range;
 
 
     if ( aRange < 1 || aRange > 3 )
     {
-      CUR.error = FT_THROW( Bad_Argument );
+      exc->error = FT_THROW( Bad_Argument );
       return FAILURE;
     }
 
-    range = &CUR.codeRangeTable[aRange - 1];
+    range = &exc->codeRangeTable[aRange - 1];
 
     if ( range->base == NULL )     /* invalid coderange */
     {
-      CUR.error = FT_THROW( Invalid_CodeRange );
+      exc->error = FT_THROW( Invalid_CodeRange );
       return FAILURE;
     }
 
@@ -1834,14 +1662,14 @@
 
     if ( aIP > range->size )
     {
-      CUR.error = FT_THROW( Code_Overflow );
+      exc->error = FT_THROW( Code_Overflow );
       return FAILURE;
     }
 
-    CUR.code     = range->base;
-    CUR.codeSize = range->size;
-    CUR.IP       = aIP;
-    CUR.curRange = aRange;
+    exc->code     = range->base;
+    exc->codeSize = range->size;
+    exc->IP       = aIP;
+    exc->curRange = aRange;
 
     return SUCCESS;
   }
@@ -1865,36 +1693,37 @@
   /*    zone     :: The affected glyph zone.                               */
   /*                                                                       */
   static void
-  Direct_Move( EXEC_OP_ TT_GlyphZone  zone,
-                        FT_UShort     point,
-                        FT_F26Dot6    distance )
+  Direct_Move( TT_ExecContext  exc,
+               TT_GlyphZone    zone,
+               FT_UShort       point,
+               FT_F26Dot6      distance )
   {
     FT_F26Dot6  v;
 
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    FT_ASSERT( !CUR.face->unpatented_hinting );
+    FT_ASSERT( !exc->face->unpatented_hinting );
 #endif
 
-    v = CUR.GS.freeVector.x;
+    v = exc->GS.freeVector.x;
 
     if ( v != 0 )
     {
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( !SUBPIXEL_HINTING                                     ||
-           ( !CUR.ignore_x_mode                                ||
-             ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
+      if ( !SUBPIXEL_HINTING                                      ||
+           ( !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, CUR.F_dot_P );
+        zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
 
       zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
     }
 
-    v = CUR.GS.freeVector.y;
+    v = exc->GS.freeVector.y;
 
     if ( v != 0 )
     {
-      zone->cur[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
+      zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
 
       zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
     }
@@ -1919,26 +1748,27 @@
   /*    zone     :: The affected glyph zone.                               */
   /*                                                                       */
   static void
-  Direct_Move_Orig( EXEC_OP_ TT_GlyphZone  zone,
-                             FT_UShort     point,
-                             FT_F26Dot6    distance )
+  Direct_Move_Orig( TT_ExecContext  exc,
+                    TT_GlyphZone    zone,
+                    FT_UShort       point,
+                    FT_F26Dot6      distance )
   {
     FT_F26Dot6  v;
 
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    FT_ASSERT( !CUR.face->unpatented_hinting );
+    FT_ASSERT( !exc->face->unpatented_hinting );
 #endif
 
-    v = CUR.GS.freeVector.x;
+    v = exc->GS.freeVector.x;
 
     if ( v != 0 )
-      zone->org[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
+      zone->org[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
 
-    v = CUR.GS.freeVector.y;
+    v = exc->GS.freeVector.y;
 
     if ( v != 0 )
-      zone->org[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
+      zone->org[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
   }
 
 
@@ -1953,15 +1783,16 @@
 
 
   static void
-  Direct_Move_X( EXEC_OP_ TT_GlyphZone  zone,
-                          FT_UShort     point,
-                          FT_F26Dot6    distance )
+  Direct_Move_X( TT_ExecContext  exc,
+                 TT_GlyphZone    zone,
+                 FT_UShort       point,
+                 FT_F26Dot6      distance )
   {
-    FT_UNUSED_EXEC;
+    FT_UNUSED( exc );
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( !SUBPIXEL_HINTING  ||
-         !CUR.ignore_x_mode )
+    if ( !SUBPIXEL_HINTING   ||
+         !exc->ignore_x_mode )
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
       zone->cur[point].x += distance;
 
@@ -1970,11 +1801,12 @@
 
 
   static void
-  Direct_Move_Y( EXEC_OP_ TT_GlyphZone  zone,
-                          FT_UShort     point,
-                          FT_F26Dot6    distance )
+  Direct_Move_Y( TT_ExecContext  exc,
+                 TT_GlyphZone    zone,
+                 FT_UShort       point,
+                 FT_F26Dot6      distance )
   {
-    FT_UNUSED_EXEC;
+    FT_UNUSED( exc );
 
     zone->cur[point].y += distance;
     zone->tags[point]  |= FT_CURVE_TAG_TOUCH_Y;
@@ -1992,22 +1824,24 @@
 
 
   static void
-  Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone  zone,
-                               FT_UShort     point,
-                               FT_F26Dot6    distance )
+  Direct_Move_Orig_X( TT_ExecContext  exc,
+                      TT_GlyphZone    zone,
+                      FT_UShort       point,
+                      FT_F26Dot6      distance )
   {
-    FT_UNUSED_EXEC;
+    FT_UNUSED( exc );
 
     zone->org[point].x += distance;
   }
 
 
   static void
-  Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone  zone,
-                               FT_UShort     point,
-                               FT_F26Dot6    distance )
+  Direct_Move_Orig_Y( TT_ExecContext  exc,
+                      TT_GlyphZone    zone,
+                      FT_UShort       point,
+                      FT_F26Dot6      distance )
   {
-    FT_UNUSED_EXEC;
+    FT_UNUSED( exc );
 
     zone->org[point].y += distance;
   }
@@ -2036,18 +1870,19 @@
   /*    before rounding.                                                   */
   /*                                                                       */
   static FT_F26Dot6
-  Round_None( EXEC_OP_ FT_F26Dot6  distance,
-                       FT_F26Dot6  compensation )
+  Round_None( TT_ExecContext  exc,
+              FT_F26Dot6      distance,
+              FT_F26Dot6      compensation )
   {
     FT_F26Dot6  val;
 
-    FT_UNUSED_EXEC;
+    FT_UNUSED( exc );
 
 
     if ( distance >= 0 )
     {
       val = distance + compensation;
-      if ( distance && val < 0 )
+      if ( val < 0 )
         val = 0;
     }
     else
@@ -2077,20 +1912,19 @@
   /*    Rounded distance.                                                  */
   /*                                                                       */
   static FT_F26Dot6
-  Round_To_Grid( EXEC_OP_ FT_F26Dot6  distance,
-                          FT_F26Dot6  compensation )
+  Round_To_Grid( TT_ExecContext  exc,
+                 FT_F26Dot6      distance,
+                 FT_F26Dot6      compensation )
   {
     FT_F26Dot6  val;
 
-    FT_UNUSED_EXEC;
+    FT_UNUSED( exc );
 
 
     if ( distance >= 0 )
     {
-      val = distance + compensation + 32;
-      if ( distance && val > 0 )
-        val &= ~63;
-      else
+      val = FT_PIX_ROUND( distance + compensation );
+      if ( val < 0 )
         val = 0;
     }
     else
@@ -2100,7 +1934,7 @@
         val = 0;
     }
 
-    return  val;
+    return val;
   }
 
 
@@ -2121,25 +1955,26 @@
   /*    Rounded distance.                                                  */
   /*                                                                       */
   static FT_F26Dot6
-  Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6  distance,
-                               FT_F26Dot6  compensation )
+  Round_To_Half_Grid( TT_ExecContext  exc,
+                      FT_F26Dot6      distance,
+                      FT_F26Dot6      compensation )
   {
     FT_F26Dot6  val;
 
-    FT_UNUSED_EXEC;
+    FT_UNUSED( exc );
 
 
     if ( distance >= 0 )
     {
       val = FT_PIX_FLOOR( distance + compensation ) + 32;
-      if ( distance && val < 0 )
-        val = 0;
+      if ( val < 0 )
+        val = 32;
     }
     else
     {
       val = -( FT_PIX_FLOOR( compensation - distance ) + 32 );
       if ( val > 0 )
-        val = 0;
+        val = -32;
     }
 
     return val;
@@ -2163,25 +1998,24 @@
   /*    Rounded distance.                                                  */
   /*                                                                       */
   static FT_F26Dot6
-  Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6  distance,
-                               FT_F26Dot6  compensation )
+  Round_Down_To_Grid( TT_ExecContext  exc,
+                      FT_F26Dot6      distance,
+                      FT_F26Dot6      compensation )
   {
     FT_F26Dot6  val;
 
-    FT_UNUSED_EXEC;
+    FT_UNUSED( exc );
 
 
     if ( distance >= 0 )
     {
-      val = distance + compensation;
-      if ( distance && val > 0 )
-        val &= ~63;
-      else
+      val = FT_PIX_FLOOR( distance + compensation );
+      if ( val < 0 )
         val = 0;
     }
     else
     {
-      val = -( ( compensation - distance ) & -64 );
+      val = -FT_PIX_FLOOR( compensation - distance );
       if ( val > 0 )
         val = 0;
     }
@@ -2207,20 +2041,19 @@
   /*    Rounded distance.                                                  */
   /*                                                                       */
   static FT_F26Dot6
-  Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6  distance,
-                             FT_F26Dot6  compensation )
+  Round_Up_To_Grid( TT_ExecContext  exc,
+                    FT_F26Dot6      distance,
+                    FT_F26Dot6      compensation )
   {
     FT_F26Dot6  val;
 
-    FT_UNUSED_EXEC;
+    FT_UNUSED( exc );
 
 
     if ( distance >= 0 )
     {
-      val = distance + compensation + 63;
-      if ( distance && val > 0 )
-        val &= ~63;
-      else
+      val = FT_PIX_CEIL( distance + compensation );
+      if ( val < 0 )
         val = 0;
     }
     else
@@ -2251,20 +2084,19 @@
   /*    Rounded distance.                                                  */
   /*                                                                       */
   static FT_F26Dot6
-  Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6  distance,
-                                 FT_F26Dot6  compensation )
+  Round_To_Double_Grid( TT_ExecContext  exc,
+                        FT_F26Dot6      distance,
+                        FT_F26Dot6      compensation )
   {
     FT_F26Dot6 val;
 
-    FT_UNUSED_EXEC;
+    FT_UNUSED( exc );
 
 
     if ( distance >= 0 )
     {
-      val = distance + compensation + 16;
-      if ( distance && val > 0 )
-        val &= ~31;
-      else
+      val = FT_PAD_ROUND( distance + compensation, 32 );
+      if ( val < 0 )
         val = 0;
     }
     else
@@ -2301,27 +2133,28 @@
   /*    before rounding.                                                   */
   /*                                                                       */
   static FT_F26Dot6
-  Round_Super( EXEC_OP_ FT_F26Dot6  distance,
-                        FT_F26Dot6  compensation )
+  Round_Super( TT_ExecContext  exc,
+               FT_F26Dot6      distance,
+               FT_F26Dot6      compensation )
   {
     FT_F26Dot6  val;
 
 
     if ( distance >= 0 )
     {
-      val = ( distance - CUR.phase + CUR.threshold + compensation ) &
-              -CUR.period;
-      if ( distance && val < 0 )
-        val = 0;
-      val += CUR.phase;
+      val = ( distance - exc->phase + exc->threshold + compensation ) &
+              -exc->period;
+      val += exc->phase;
+      if ( val < 0 )
+        val = exc->phase;
     }
     else
     {
-      val = -( ( CUR.threshold - CUR.phase - distance + compensation ) &
-               -CUR.period );
+      val = -( ( exc->threshold - exc->phase - distance + compensation ) &
+               -exc->period );
+      val -= exc->phase;
       if ( val > 0 )
-        val = 0;
-      val -= CUR.phase;
+        val = -exc->phase;
     }
 
     return val;
@@ -2349,27 +2182,28 @@
   /*    greater precision.                                                 */
   /*                                                                       */
   static FT_F26Dot6
-  Round_Super_45( EXEC_OP_ FT_F26Dot6  distance,
-                           FT_F26Dot6  compensation )
+  Round_Super_45( TT_ExecContext  exc,
+                  FT_F26Dot6      distance,
+                  FT_F26Dot6      compensation )
   {
     FT_F26Dot6  val;
 
 
     if ( distance >= 0 )
     {
-      val = ( ( distance - CUR.phase + CUR.threshold + compensation ) /
-                CUR.period ) * CUR.period;
-      if ( distance && val < 0 )
-        val = 0;
-      val += CUR.phase;
+      val = ( ( distance - exc->phase + exc->threshold + compensation ) /
+                exc->period ) * exc->period;
+      val += exc->phase;
+      if ( val < 0 )
+        val = exc->phase;
     }
     else
     {
-      val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) /
-                   CUR.period ) * CUR.period );
+      val = -( ( ( exc->threshold - exc->phase - distance + compensation ) /
+                   exc->period ) * exc->period );
+      val -= exc->phase;
       if ( val > 0 )
-        val = 0;
-      val -= CUR.phase;
+        val = -exc->phase;
     }
 
     return val;
@@ -2388,40 +2222,41 @@
   /*    round_mode :: The rounding mode to be used.                        */
   /*                                                                       */
   static void
-  Compute_Round( EXEC_OP_ FT_Byte  round_mode )
+  Compute_Round( TT_ExecContext  exc,
+                 FT_Byte         round_mode )
   {
     switch ( round_mode )
     {
     case TT_Round_Off:
-      CUR.func_round = (TT_Round_Func)Round_None;
+      exc->func_round = (TT_Round_Func)Round_None;
       break;
 
     case TT_Round_To_Grid:
-      CUR.func_round = (TT_Round_Func)Round_To_Grid;
+      exc->func_round = (TT_Round_Func)Round_To_Grid;
       break;
 
     case TT_Round_Up_To_Grid:
-      CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
+      exc->func_round = (TT_Round_Func)Round_Up_To_Grid;
       break;
 
     case TT_Round_Down_To_Grid:
-      CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
+      exc->func_round = (TT_Round_Func)Round_Down_To_Grid;
       break;
 
     case TT_Round_To_Half_Grid:
-      CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
+      exc->func_round = (TT_Round_Func)Round_To_Half_Grid;
       break;
 
     case TT_Round_To_Double_Grid:
-      CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
+      exc->func_round = (TT_Round_Func)Round_To_Double_Grid;
       break;
 
     case TT_Round_Super:
-      CUR.func_round = (TT_Round_Func)Round_Super;
+      exc->func_round = (TT_Round_Func)Round_Super;
       break;
 
     case TT_Round_Super_45:
-      CUR.func_round = (TT_Round_Func)Round_Super_45;
+      exc->func_round = (TT_Round_Func)Round_Super_45;
       break;
     }
   }
@@ -2441,57 +2276,58 @@
   /*    selector   :: The SROUND opcode.                                   */
   /*                                                                       */
   static void
-  SetSuperRound( EXEC_OP_ FT_F26Dot6  GridPeriod,
-                          FT_Long     selector )
+  SetSuperRound( TT_ExecContext  exc,
+                 FT_F2Dot14      GridPeriod,
+                 FT_Long         selector )
   {
     switch ( (FT_Int)( selector & 0xC0 ) )
     {
       case 0:
-        CUR.period = GridPeriod / 2;
+        exc->period = GridPeriod / 2;
         break;
 
       case 0x40:
-        CUR.period = GridPeriod;
+        exc->period = GridPeriod;
         break;
 
       case 0x80:
-        CUR.period = GridPeriod * 2;
+        exc->period = GridPeriod * 2;
         break;
 
       /* This opcode is reserved, but... */
-
       case 0xC0:
-        CUR.period = GridPeriod;
+        exc->period = GridPeriod;
         break;
     }
 
     switch ( (FT_Int)( selector & 0x30 ) )
     {
     case 0:
-      CUR.phase = 0;
+      exc->phase = 0;
       break;
 
     case 0x10:
-      CUR.phase = CUR.period / 4;
+      exc->phase = exc->period / 4;
       break;
 
     case 0x20:
-      CUR.phase = CUR.period / 2;
+      exc->phase = exc->period / 2;
       break;
 
     case 0x30:
-      CUR.phase = CUR.period * 3 / 4;
+      exc->phase = exc->period * 3 / 4;
       break;
     }
 
     if ( ( selector & 0x0F ) == 0 )
-      CUR.threshold = CUR.period - 1;
+      exc->threshold = exc->period - 1;
     else
-      CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8;
+      exc->threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * exc->period / 8;
 
-    CUR.period    /= 256;
-    CUR.phase     /= 256;
-    CUR.threshold /= 256;
+    /* convert to F26Dot6 format */
+    exc->period    >>= 8;
+    exc->phase     >>= 8;
+    exc->threshold >>= 8;
   }
 
 
@@ -2512,16 +2348,17 @@
   /*    The distance in F26dot6 format.                                    */
   /*                                                                       */
   static FT_F26Dot6
-  Project( EXEC_OP_ FT_Pos  dx,
-                    FT_Pos  dy )
+  Project( TT_ExecContext  exc,
+           FT_Pos          dx,
+           FT_Pos          dy )
   {
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    FT_ASSERT( !CUR.face->unpatented_hinting );
+    FT_ASSERT( !exc->face->unpatented_hinting );
 #endif
 
-    return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
-                        CUR.GS.projVector.x,
-                        CUR.GS.projVector.y );
+    return TT_DotFix14( dx, dy,
+                        exc->GS.projVector.x,
+                        exc->GS.projVector.y );
   }
 
 
@@ -2542,12 +2379,13 @@
   /*    The distance in F26dot6 format.                                    */
   /*                                                                       */
   static FT_F26Dot6
-  Dual_Project( EXEC_OP_ FT_Pos  dx,
-                         FT_Pos  dy )
+  Dual_Project( TT_ExecContext  exc,
+                FT_Pos          dx,
+                FT_Pos          dy )
   {
-    return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
-                        CUR.GS.dualVector.x,
-                        CUR.GS.dualVector.y );
+    return TT_DotFix14( dx, dy,
+                        exc->GS.dualVector.x,
+                        exc->GS.dualVector.y );
   }
 
 
@@ -2568,10 +2406,11 @@
   /*    The distance in F26dot6 format.                                    */
   /*                                                                       */
   static FT_F26Dot6
-  Project_x( EXEC_OP_ FT_Pos  dx,
-                      FT_Pos  dy )
+  Project_x( TT_ExecContext  exc,
+             FT_Pos          dx,
+             FT_Pos          dy )
   {
-    FT_UNUSED_EXEC;
+    FT_UNUSED( exc );
     FT_UNUSED( dy );
 
     return dx;
@@ -2595,10 +2434,11 @@
   /*    The distance in F26dot6 format.                                    */
   /*                                                                       */
   static FT_F26Dot6
-  Project_y( EXEC_OP_ FT_Pos  dx,
-                      FT_Pos  dy )
+  Project_y( TT_ExecContext  exc,
+             FT_Pos          dx,
+             FT_Pos          dy )
   {
-    FT_UNUSED_EXEC;
+    FT_UNUSED( exc );
     FT_UNUSED( dx );
 
     return dy;
@@ -2615,101 +2455,101 @@
   /*    to the current graphics state.                                     */
   /*                                                                       */
   static void
-  Compute_Funcs( EXEC_OP )
+  Compute_Funcs( TT_ExecContext  exc )
   {
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    if ( CUR.face->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.                                   */
-      CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 &&
-                                      CUR.GS.freeVector.x == 0x4000 );
+      /* 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.     */
-      CUR.GS.projVector.x = 0;
-      CUR.GS.projVector.y = 0;
-      CUR.GS.freeVector.x = 0;
-      CUR.GS.freeVector.y = 0;
+      exc->GS.projVector.x = 0;
+      exc->GS.projVector.y = 0;
+      exc->GS.freeVector.x = 0;
+      exc->GS.freeVector.y = 0;
 
-      if ( CUR.GS.both_x_axis )
+      if ( exc->GS.both_x_axis )
       {
-        CUR.func_project   = Project_x;
-        CUR.func_move      = Direct_Move_X;
-        CUR.func_move_orig = Direct_Move_Orig_X;
+        exc->func_project   = Project_x;
+        exc->func_move      = Direct_Move_X;
+        exc->func_move_orig = Direct_Move_Orig_X;
       }
       else
       {
-        CUR.func_project   = Project_y;
-        CUR.func_move      = Direct_Move_Y;
-        CUR.func_move_orig = Direct_Move_Orig_Y;
+        exc->func_project   = Project_y;
+        exc->func_move      = Direct_Move_Y;
+        exc->func_move_orig = Direct_Move_Orig_Y;
       }
 
-      if ( CUR.GS.dualVector.x == 0x4000 )
-        CUR.func_dualproj = Project_x;
-      else if ( CUR.GS.dualVector.y == 0x4000 )
-        CUR.func_dualproj = Project_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
-        CUR.func_dualproj = Dual_Project;
+        exc->func_dualproj = Dual_Project;
 
       /* Force recalculation of cached aspect ratio */
-      CUR.tt_metrics.ratio = 0;
+      exc->tt_metrics.ratio = 0;
 
       return;
     }
 #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */
 
-    if ( CUR.GS.freeVector.x == 0x4000 )
-      CUR.F_dot_P = CUR.GS.projVector.x;
-    else if ( CUR.GS.freeVector.y == 0x4000 )
-      CUR.F_dot_P = CUR.GS.projVector.y;
+    if ( exc->GS.freeVector.x == 0x4000 )
+      exc->F_dot_P = exc->GS.projVector.x;
+    else if ( exc->GS.freeVector.y == 0x4000 )
+      exc->F_dot_P = exc->GS.projVector.y;
     else
-      CUR.F_dot_P = ( (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x +
-                      (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y ) >>
-                    14;
+      exc->F_dot_P =
+        ( (FT_Long)exc->GS.projVector.x * exc->GS.freeVector.x +
+          (FT_Long)exc->GS.projVector.y * exc->GS.freeVector.y ) >> 14;
 
-    if ( CUR.GS.projVector.x == 0x4000 )
-      CUR.func_project = (TT_Project_Func)Project_x;
-    else if ( CUR.GS.projVector.y == 0x4000 )
-      CUR.func_project = (TT_Project_Func)Project_y;
+    if ( exc->GS.projVector.x == 0x4000 )
+      exc->func_project = (TT_Project_Func)Project_x;
+    else if ( exc->GS.projVector.y == 0x4000 )
+      exc->func_project = (TT_Project_Func)Project_y;
     else
-      CUR.func_project = (TT_Project_Func)Project;
+      exc->func_project = (TT_Project_Func)Project;
 
-    if ( CUR.GS.dualVector.x == 0x4000 )
-      CUR.func_dualproj = (TT_Project_Func)Project_x;
-    else if ( CUR.GS.dualVector.y == 0x4000 )
-      CUR.func_dualproj = (TT_Project_Func)Project_y;
+    if ( exc->GS.dualVector.x == 0x4000 )
+      exc->func_dualproj = (TT_Project_Func)Project_x;
+    else if ( exc->GS.dualVector.y == 0x4000 )
+      exc->func_dualproj = (TT_Project_Func)Project_y;
     else
-      CUR.func_dualproj = (TT_Project_Func)Dual_Project;
+      exc->func_dualproj = (TT_Project_Func)Dual_Project;
 
-    CUR.func_move      = (TT_Move_Func)Direct_Move;
-    CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig;
+    exc->func_move      = (TT_Move_Func)Direct_Move;
+    exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig;
 
-    if ( CUR.F_dot_P == 0x4000L )
+    if ( exc->F_dot_P == 0x4000L )
     {
-      if ( CUR.GS.freeVector.x == 0x4000 )
+      if ( exc->GS.freeVector.x == 0x4000 )
       {
-        CUR.func_move      = (TT_Move_Func)Direct_Move_X;
-        CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
+        exc->func_move      = (TT_Move_Func)Direct_Move_X;
+        exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_X;
       }
-      else if ( CUR.GS.freeVector.y == 0x4000 )
+      else if ( exc->GS.freeVector.y == 0x4000 )
       {
-        CUR.func_move      = (TT_Move_Func)Direct_Move_Y;
-        CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
+        exc->func_move      = (TT_Move_Func)Direct_Move_Y;
+        exc->func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y;
       }
     }
 
     /* at small sizes, F_dot_P can become too small, resulting   */
     /* in overflows and `spikes' in a number of glyphs like `w'. */
 
-    if ( FT_ABS( CUR.F_dot_P ) < 0x400L )
-      CUR.F_dot_P = 0x4000L;
+    if ( FT_ABS( exc->F_dot_P ) < 0x400L )
+      exc->F_dot_P = 0x4000L;
 
     /* Disable cached aspect ratio */
-    CUR.tt_metrics.ratio = 0;
+    exc->tt_metrics.ratio = 0;
   }
 
 
@@ -2732,18 +2572,16 @@
   /*    Returns FAILURE if a vector parameter is zero.                     */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    In case Vx and Vy are both zero, Normalize() returns SUCCESS, and  */
+  /*    In case Vx and Vy are both zero, `Normalize' returns SUCCESS, and  */
   /*    R is undefined.                                                    */
   /*                                                                       */
   static FT_Bool
-  Normalize( EXEC_OP_ FT_F26Dot6      Vx,
-                      FT_F26Dot6      Vy,
-                      FT_UnitVector*  R )
+  Normalize( FT_F26Dot6      Vx,
+             FT_F26Dot6      Vy,
+             FT_UnitVector*  R )
   {
     FT_F26Dot6  W;
 
-    FT_UNUSED_EXEC;
-
 
     if ( FT_ABS( Vx ) < 0x4000L && FT_ABS( Vy ) < 0x4000L )
     {
@@ -2774,1062 +2612,12 @@
   /*************************************************************************/
 
 
-  static FT_Bool
-  Ins_SxVTL( EXEC_OP_ FT_UShort       aIdx1,
-                      FT_UShort       aIdx2,
-                      FT_Int          aOpc,
-                      FT_UnitVector*  Vec )
-  {
-    FT_Long     A, B, C;
-    FT_Vector*  p1;
-    FT_Vector*  p2;
-
-
-    if ( BOUNDS( aIdx1, CUR.zp2.n_points ) ||
-         BOUNDS( aIdx2, CUR.zp1.n_points ) )
-    {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
-      return FAILURE;
-    }
-
-    p1 = CUR.zp1.cur + aIdx2;
-    p2 = CUR.zp2.cur + aIdx1;
-
-    A = p1->x - p2->x;
-    B = p1->y - p2->y;
-
-    /* If p1 == p2, SPVTL and SFVTL behave the same as */
-    /* SPVTCA[X] and SFVTCA[X], respectively.          */
-    /*                                                 */
-    /* Confirmed by Greg Hitchcock.                    */
-
-    if ( A == 0 && B == 0 )
-    {
-      A    = 0x4000;
-      aOpc = 0;
-    }
-
-    if ( ( aOpc & 1 ) != 0 )
-    {
-      C =  B;   /* counter clockwise rotation */
-      B =  A;
-      A = -C;
-    }
-
-    NORMalize( A, B, Vec );
-
-    return SUCCESS;
-  }
-
-
-  /* When not using the big switch statements, the interpreter uses a */
-  /* call table defined later below in this source.  Each opcode must */
-  /* thus have a corresponding function, even trivial ones.           */
-  /*                                                                  */
-  /* They are all defined there.                                      */
-
-#define DO_SVTCA                            \
-  {                                         \
-    FT_Short  A, B;                         \
-                                            \
-                                            \
-    A = (FT_Short)( CUR.opcode & 1 ) << 14; \
-    B = A ^ (FT_Short)0x4000;               \
-                                            \
-    CUR.GS.freeVector.x = A;                \
-    CUR.GS.projVector.x = A;                \
-    CUR.GS.dualVector.x = A;                \
-                                            \
-    CUR.GS.freeVector.y = B;                \
-    CUR.GS.projVector.y = B;                \
-    CUR.GS.dualVector.y = B;                \
-                                            \
-    COMPUTE_Funcs();                        \
-  }
-
-
-#define DO_SPVTCA                           \
-  {                                         \
-    FT_Short  A, B;                         \
-                                            \
-                                            \
-    A = (FT_Short)( CUR.opcode & 1 ) << 14; \
-    B = A ^ (FT_Short)0x4000;               \
-                                            \
-    CUR.GS.projVector.x = A;                \
-    CUR.GS.dualVector.x = A;                \
-                                            \
-    CUR.GS.projVector.y = B;                \
-    CUR.GS.dualVector.y = B;                \
-                                            \
-    GUESS_VECTOR( freeVector );             \
-                                            \
-    COMPUTE_Funcs();                        \
-  }
-
-
-#define DO_SFVTCA                           \
-  {                                         \
-    FT_Short  A, B;                         \
-                                            \
-                                            \
-    A = (FT_Short)( CUR.opcode & 1 ) << 14; \
-    B = A ^ (FT_Short)0x4000;               \
-                                            \
-    CUR.GS.freeVector.x = A;                \
-    CUR.GS.freeVector.y = B;                \
-                                            \
-    GUESS_VECTOR( projVector );             \
-                                            \
-    COMPUTE_Funcs();                        \
-  }
-
-
-#define DO_SPVTL                                      \
-    if ( INS_SxVTL( (FT_UShort)args[1],               \
-                    (FT_UShort)args[0],               \
-                    CUR.opcode,                       \
-                    &CUR.GS.projVector ) == SUCCESS ) \
-    {                                                 \
-      CUR.GS.dualVector = CUR.GS.projVector;          \
-      GUESS_VECTOR( freeVector );                     \
-      COMPUTE_Funcs();                                \
-    }
-
-
-#define DO_SFVTL                                      \
-    if ( INS_SxVTL( (FT_UShort)args[1],               \
-                    (FT_UShort)args[0],               \
-                    CUR.opcode,                       \
-                    &CUR.GS.freeVector ) == SUCCESS ) \
-    {                                                 \
-      GUESS_VECTOR( projVector );                     \
-      COMPUTE_Funcs();                                \
-    }
-
-
-#define DO_SFVTPV                          \
-    GUESS_VECTOR( projVector );            \
-    CUR.GS.freeVector = CUR.GS.projVector; \
-    COMPUTE_Funcs();
-
-
-#define DO_SPVFS                                \
-  {                                             \
-    FT_Short  S;                                \
-    FT_Long   X, Y;                             \
-                                                \
-                                                \
-    /* Only use low 16bits, then sign extend */ \
-    S = (FT_Short)args[1];                      \
-    Y = (FT_Long)S;                             \
-    S = (FT_Short)args[0];                      \
-    X = (FT_Long)S;                             \
-                                                \
-    NORMalize( X, Y, &CUR.GS.projVector );      \
-                                                \
-    CUR.GS.dualVector = CUR.GS.projVector;      \
-    GUESS_VECTOR( freeVector );                 \
-    COMPUTE_Funcs();                            \
-  }
-
-
-#define DO_SFVFS                                \
-  {                                             \
-    FT_Short  S;                                \
-    FT_Long   X, Y;                             \
-                                                \
-                                                \
-    /* Only use low 16bits, then sign extend */ \
-    S = (FT_Short)args[1];                      \
-    Y = (FT_Long)S;                             \
-    S = (FT_Short)args[0];                      \
-    X = S;                                      \
-                                                \
-    NORMalize( X, Y, &CUR.GS.freeVector );      \
-    GUESS_VECTOR( projVector );                 \
-    COMPUTE_Funcs();                            \
-  }
-
-
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-#define DO_GPV                                   \
-    if ( CUR.face->unpatented_hinting )          \
-    {                                            \
-      args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \
-      args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \
-    }                                            \
-    else                                         \
-    {                                            \
-      args[0] = CUR.GS.projVector.x;             \
-      args[1] = CUR.GS.projVector.y;             \
-    }
-#else
-#define DO_GPV                                   \
-    args[0] = CUR.GS.projVector.x;               \
-    args[1] = CUR.GS.projVector.y;
-#endif
-
-
-#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-#define DO_GFV                                   \
-    if ( CUR.face->unpatented_hinting )          \
-    {                                            \
-      args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \
-      args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \
-    }                                            \
-    else                                         \
-    {                                            \
-      args[0] = CUR.GS.freeVector.x;             \
-      args[1] = CUR.GS.freeVector.y;             \
-    }
-#else
-#define DO_GFV                                   \
-    args[0] = CUR.GS.freeVector.x;               \
-    args[1] = CUR.GS.freeVector.y;
-#endif
-
-
-#define DO_SRP0                      \
-    CUR.GS.rp0 = (FT_UShort)args[0];
-
-
-#define DO_SRP1                      \
-    CUR.GS.rp1 = (FT_UShort)args[0];
-
-
-#define DO_SRP2                      \
-    CUR.GS.rp2 = (FT_UShort)args[0];
-
-
-#define DO_RTHG                                         \
-    CUR.GS.round_state = TT_Round_To_Half_Grid;         \
-    CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
-
-
-#define DO_RTG                                     \
-    CUR.GS.round_state = TT_Round_To_Grid;         \
-    CUR.func_round = (TT_Round_Func)Round_To_Grid;
-
-
-#define DO_RTDG                                           \
-    CUR.GS.round_state = TT_Round_To_Double_Grid;         \
-    CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
-
-
-#define DO_RUTG                                       \
-    CUR.GS.round_state = TT_Round_Up_To_Grid;         \
-    CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
-
-
-#define DO_RDTG                                         \
-    CUR.GS.round_state = TT_Round_Down_To_Grid;         \
-    CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
-
-
-#define DO_ROFF                                 \
-    CUR.GS.round_state = TT_Round_Off;          \
-    CUR.func_round = (TT_Round_Func)Round_None;
-
-
-#define DO_SROUND                                \
-    SET_SuperRound( 0x4000, args[0] );           \
-    CUR.GS.round_state = TT_Round_Super;         \
-    CUR.func_round = (TT_Round_Func)Round_Super;
-
-
-#define DO_S45ROUND                                 \
-    SET_SuperRound( 0x2D41, args[0] );              \
-    CUR.GS.round_state = TT_Round_Super_45;         \
-    CUR.func_round = (TT_Round_Func)Round_Super_45;
-
-
-#define DO_SLOOP                            \
-    if ( args[0] < 0 )                      \
-      CUR.error = FT_THROW( Bad_Argument ); \
-    else                                    \
-      CUR.GS.loop = args[0];
-
-
-#define DO_SMD                         \
-    CUR.GS.minimum_distance = args[0];
-
-
-#define DO_SCVTCI                                     \
-    CUR.GS.control_value_cutin = (FT_F26Dot6)args[0];
-
-
-#define DO_SSWCI                                     \
-    CUR.GS.single_width_cutin = (FT_F26Dot6)args[0];
-
-
-#define DO_SSW                                                     \
-    CUR.GS.single_width_value = FT_MulFix( args[0],                \
-                                           CUR.tt_metrics.scale );
-
-
-#define DO_FLIPON            \
-    CUR.GS.auto_flip = TRUE;
-
-
-#define DO_FLIPOFF            \
-    CUR.GS.auto_flip = FALSE;
-
-
-#define DO_SDB                             \
-    CUR.GS.delta_base = (FT_Short)args[0];
-
-
-#define DO_SDS                              \
-    CUR.GS.delta_shift = (FT_Short)args[0];
-
-
-#define DO_MD  /* nothing */
-
-
-#define DO_MPPEM              \
-    args[0] = CURRENT_Ppem();
-
-
-  /* Note: The pointSize should be irrelevant in a given font program; */
-  /*       we thus decide to return only the ppem.                     */
-#if 0
-
-#define DO_MPS                       \
-    args[0] = CUR.metrics.pointSize;
-
-#else
-
-#define DO_MPS                \
-    args[0] = CURRENT_Ppem();
-
-#endif /* 0 */
-
-
-#define DO_DUP         \
-    args[1] = args[0];
-
-
-#define DO_CLEAR     \
-    CUR.new_top = 0;
-
-
-#define DO_SWAP        \
-  {                    \
-    FT_Long  L;        \
-                       \
-                       \
-    L       = args[0]; \
-    args[0] = args[1]; \
-    args[1] = L;       \
-  }
-
-
-#define DO_DEPTH       \
-    args[0] = CUR.top;
-
-
-#define DO_CINDEX                                  \
-  {                                                \
-    FT_Long  L;                                    \
-                                                   \
-                                                   \
-    L = args[0];                                   \
-                                                   \
-    if ( L <= 0 || L > CUR.args )                  \
-    {                                              \
-      if ( CUR.pedantic_hinting )                  \
-        CUR.error = FT_THROW( Invalid_Reference ); \
-      args[0] = 0;                                 \
-    }                                              \
-    else                                           \
-      args[0] = CUR.stack[CUR.args - L];           \
-  }
-
-
-#define DO_JROT                                                    \
-    if ( args[1] != 0 )                                            \
-    {                                                              \
-      if ( args[0] == 0 && CUR.args == 0 )                         \
-        CUR.error = FT_THROW( Bad_Argument );                      \
-      CUR.IP += args[0];                                           \
-      if ( CUR.IP < 0                                           || \
-           ( CUR.callTop > 0                                  &&   \
-             CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) )  \
-        CUR.error = FT_THROW( Bad_Argument );                      \
-      CUR.step_ins = FALSE;                                        \
-    }
-
-
-#define DO_JMPR                                                  \
-    if ( args[0] == 0 && CUR.args == 0 )                         \
-      CUR.error = FT_THROW( Bad_Argument );                      \
-    CUR.IP += args[0];                                           \
-    if ( CUR.IP < 0                                           || \
-         ( CUR.callTop > 0                                  &&   \
-           CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) )  \
-      CUR.error = FT_THROW( Bad_Argument );                      \
-    CUR.step_ins = FALSE;
-
-
-#define DO_JROF                                                    \
-    if ( args[1] == 0 )                                            \
-    {                                                              \
-      if ( args[0] == 0 && CUR.args == 0 )                         \
-        CUR.error = FT_THROW( Bad_Argument );                      \
-      CUR.IP += args[0];                                           \
-      if ( CUR.IP < 0                                           || \
-           ( CUR.callTop > 0                                  &&   \
-             CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) )  \
-        CUR.error = FT_THROW( Bad_Argument );                      \
-      CUR.step_ins = FALSE;                                        \
-    }
-
-
-#define DO_LT                        \
-    args[0] = ( args[0] < args[1] );
-
-
-#define DO_LTEQ                       \
-    args[0] = ( args[0] <= args[1] );
-
-
-#define DO_GT                        \
-    args[0] = ( args[0] > args[1] );
-
-
-#define DO_GTEQ                       \
-    args[0] = ( args[0] >= args[1] );
-
-
-#define DO_EQ                         \
-    args[0] = ( args[0] == args[1] );
-
-
-#define DO_NEQ                        \
-    args[0] = ( args[0] != args[1] );
-
-
-#define DO_ODD                                                  \
-    args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 );
-
-
-#define DO_EVEN                                                \
-    args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 );
-
-
-#define DO_AND                        \
-    args[0] = ( args[0] && args[1] );
-
-
-#define DO_OR                         \
-    args[0] = ( args[0] || args[1] );
-
-
-#define DO_NOT          \
-    args[0] = !args[0];
-
-
-#define DO_ADD          \
-    args[0] += args[1];
-
-
-#define DO_SUB          \
-    args[0] -= args[1];
-
-
-#define DO_DIV                                               \
-    if ( args[1] == 0 )                                      \
-      CUR.error = FT_THROW( Divide_By_Zero );                \
-    else                                                     \
-      args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] );
-
-
-#define DO_MUL                                    \
-    args[0] = FT_MulDiv( args[0], args[1], 64L );
-
-
-#define DO_ABS                   \
-    args[0] = FT_ABS( args[0] );
-
-
-#define DO_NEG          \
-    args[0] = -args[0];
-
-
-#define DO_FLOOR    \
-    args[0] = FT_PIX_FLOOR( args[0] );
-
-
-#define DO_CEILING                    \
-    args[0] = FT_PIX_CEIL( args[0] );
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-
-#define DO_RS                                             \
-   {                                                      \
-     FT_ULong  I = (FT_ULong)args[0];                     \
-                                                          \
-                                                          \
-     if ( BOUNDSL( I, CUR.storeSize ) )                   \
-     {                                                    \
-       if ( CUR.pedantic_hinting )                        \
-         ARRAY_BOUND_ERROR;                               \
-       else                                               \
-         args[0] = 0;                                     \
-     }                                                    \
-     else                                                 \
-     {                                                    \
-       /* subpixel hinting - avoid Typeman Dstroke and */ \
-       /* IStroke and Vacuform rounds                  */ \
-                                                          \
-       if ( SUBPIXEL_HINTING                           && \
-            CUR.ignore_x_mode                          && \
-            ( ( I == 24                            &&     \
-                ( CUR.face->sph_found_func_flags &        \
-                  ( SPH_FDEF_SPACING_1 |                  \
-                    SPH_FDEF_SPACING_2 )         ) ) ||   \
-              ( I == 22                      &&           \
-                ( CUR.sph_in_func_flags    &              \
-                  SPH_FDEF_TYPEMAN_STROKES ) )       ||   \
-              ( I == 8                             &&     \
-                ( CUR.face->sph_found_func_flags &        \
-                  SPH_FDEF_VACUFORM_ROUND_1      ) &&     \
-                  CUR.iup_called                   ) ) )  \
-         args[0] = 0;                                     \
-       else                                               \
-         args[0] = CUR.storage[I];                        \
-     }                                                    \
-   }
-
-#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-#define DO_RS                           \
-   {                                    \
-     FT_ULong  I = (FT_ULong)args[0];   \
-                                        \
-                                        \
-     if ( BOUNDSL( I, CUR.storeSize ) ) \
-     {                                  \
-       if ( CUR.pedantic_hinting )      \
-       {                                \
-         ARRAY_BOUND_ERROR;             \
-       }                                \
-       else                             \
-         args[0] = 0;                   \
-     }                                  \
-     else                               \
-       args[0] = CUR.storage[I];        \
-   }
-
-#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-
-
-#define DO_WS                           \
-   {                                    \
-     FT_ULong  I = (FT_ULong)args[0];   \
-                                        \
-                                        \
-     if ( BOUNDSL( I, CUR.storeSize ) ) \
-     {                                  \
-       if ( CUR.pedantic_hinting )      \
-       {                                \
-         ARRAY_BOUND_ERROR;             \
-       }                                \
-     }                                  \
-     else                               \
-       CUR.storage[I] = args[1];        \
-   }
-
-
-#define DO_RCVT                          \
-   {                                     \
-     FT_ULong  I = (FT_ULong)args[0];    \
-                                         \
-                                         \
-     if ( BOUNDSL( I, CUR.cvtSize ) )    \
-     {                                   \
-       if ( CUR.pedantic_hinting )       \
-       {                                 \
-         ARRAY_BOUND_ERROR;              \
-       }                                 \
-       else                              \
-         args[0] = 0;                    \
-     }                                   \
-     else                                \
-       args[0] = CUR_Func_read_cvt( I ); \
-   }
-
-
-#define DO_WCVTP                         \
-   {                                     \
-     FT_ULong  I = (FT_ULong)args[0];    \
-                                         \
-                                         \
-     if ( BOUNDSL( I, CUR.cvtSize ) )    \
-     {                                   \
-       if ( CUR.pedantic_hinting )       \
-       {                                 \
-         ARRAY_BOUND_ERROR;              \
-       }                                 \
-     }                                   \
-     else                                \
-       CUR_Func_write_cvt( I, args[1] ); \
-   }
-
-
-#define DO_WCVTF                                                \
-   {                                                            \
-     FT_ULong  I = (FT_ULong)args[0];                           \
-                                                                \
-                                                                \
-     if ( BOUNDSL( I, CUR.cvtSize ) )                           \
-     {                                                          \
-       if ( CUR.pedantic_hinting )                              \
-       {                                                        \
-         ARRAY_BOUND_ERROR;                                     \
-       }                                                        \
-     }                                                          \
-     else                                                       \
-       CUR.cvt[I] = FT_MulFix( args[1], CUR.tt_metrics.scale ); \
-   }
-
-
-#define DO_DEBUG                          \
-    CUR.error = FT_THROW( Debug_OpCode );
-
-
-#define DO_ROUND                                                   \
-    args[0] = CUR_Func_round(                                      \
-                args[0],                                           \
-                CUR.tt_metrics.compensations[CUR.opcode - 0x68] );
-
-
-#define DO_NROUND                                                            \
-    args[0] = ROUND_None( args[0],                                           \
-                          CUR.tt_metrics.compensations[CUR.opcode - 0x6C] );
-
-
-#define DO_MAX               \
-    if ( args[1] > args[0] ) \
-      args[0] = args[1];
-
-
-#define DO_MIN               \
-    if ( args[1] < args[0] ) \
-      args[0] = args[1];
-
-
-#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
-
-
-#undef  ARRAY_BOUND_ERROR
-#define ARRAY_BOUND_ERROR                        \
-    {                                            \
-      CUR.error = FT_THROW( Invalid_Reference ); \
-      return;                                    \
-    }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SVTCA[a]:     Set (F and P) Vectors to Coordinate Axis                */
-  /* Opcode range: 0x00-0x01                                               */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_SVTCA( INS_ARG )
-  {
-    DO_SVTCA
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SPVTCA[a]:    Set PVector to Coordinate Axis                          */
-  /* Opcode range: 0x02-0x03                                               */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_SPVTCA( INS_ARG )
-  {
-    DO_SPVTCA
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SFVTCA[a]:    Set FVector to Coordinate Axis                          */
-  /* Opcode range: 0x04-0x05                                               */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_SFVTCA( INS_ARG )
-  {
-    DO_SFVTCA
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SPVTL[a]:     Set PVector To Line                                     */
-  /* Opcode range: 0x06-0x07                                               */
-  /* Stack:        uint32 uint32 -->                                       */
-  /*                                                                       */
-  static void
-  Ins_SPVTL( INS_ARG )
-  {
-    DO_SPVTL
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SFVTL[a]:     Set FVector To Line                                     */
-  /* Opcode range: 0x08-0x09                                               */
-  /* Stack:        uint32 uint32 -->                                       */
-  /*                                                                       */
-  static void
-  Ins_SFVTL( INS_ARG )
-  {
-    DO_SFVTL
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SFVTPV[]:     Set FVector To PVector                                  */
-  /* Opcode range: 0x0E                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_SFVTPV( INS_ARG )
-  {
-    DO_SFVTPV
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SPVFS[]:      Set PVector From Stack                                  */
-  /* Opcode range: 0x0A                                                    */
-  /* Stack:        f2.14 f2.14 -->                                         */
-  /*                                                                       */
-  static void
-  Ins_SPVFS( INS_ARG )
-  {
-    DO_SPVFS
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SFVFS[]:      Set FVector From Stack                                  */
-  /* Opcode range: 0x0B                                                    */
-  /* Stack:        f2.14 f2.14 -->                                         */
-  /*                                                                       */
-  static void
-  Ins_SFVFS( INS_ARG )
-  {
-    DO_SFVFS
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* GPV[]:        Get Projection Vector                                   */
-  /* Opcode range: 0x0C                                                    */
-  /* Stack:        ef2.14 --> ef2.14                                       */
-  /*                                                                       */
-  static void
-  Ins_GPV( INS_ARG )
-  {
-    DO_GPV
-  }
-
-
-  /*************************************************************************/
-  /* GFV[]:        Get Freedom Vector                                      */
-  /* Opcode range: 0x0D                                                    */
-  /* Stack:        ef2.14 --> ef2.14                                       */
-  /*                                                                       */
-  static void
-  Ins_GFV( INS_ARG )
-  {
-    DO_GFV
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SRP0[]:       Set Reference Point 0                                   */
-  /* Opcode range: 0x10                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SRP0( INS_ARG )
-  {
-    DO_SRP0
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SRP1[]:       Set Reference Point 1                                   */
-  /* Opcode range: 0x11                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SRP1( INS_ARG )
-  {
-    DO_SRP1
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SRP2[]:       Set Reference Point 2                                   */
-  /* Opcode range: 0x12                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SRP2( INS_ARG )
-  {
-    DO_SRP2
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* RTHG[]:       Round To Half Grid                                      */
-  /* Opcode range: 0x19                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_RTHG( INS_ARG )
-  {
-    DO_RTHG
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* RTG[]:        Round To Grid                                           */
-  /* Opcode range: 0x18                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_RTG( INS_ARG )
-  {
-    DO_RTG
-  }
-
-
-  /*************************************************************************/
-  /* RTDG[]:       Round To Double Grid                                    */
-  /* Opcode range: 0x3D                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_RTDG( INS_ARG )
-  {
-    DO_RTDG
-  }
-
-
-  /*************************************************************************/
-  /* RUTG[]:       Round Up To Grid                                        */
-  /* Opcode range: 0x7C                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_RUTG( INS_ARG )
-  {
-    DO_RUTG
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* RDTG[]:       Round Down To Grid                                      */
-  /* Opcode range: 0x7D                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_RDTG( INS_ARG )
-  {
-    DO_RDTG
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* ROFF[]:       Round OFF                                               */
-  /* Opcode range: 0x7A                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_ROFF( INS_ARG )
-  {
-    DO_ROFF
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SROUND[]:     Super ROUND                                             */
-  /* Opcode range: 0x76                                                    */
-  /* Stack:        Eint8 -->                                               */
-  /*                                                                       */
-  static void
-  Ins_SROUND( INS_ARG )
-  {
-    DO_SROUND
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* S45ROUND[]:   Super ROUND 45 degrees                                  */
-  /* Opcode range: 0x77                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_S45ROUND( INS_ARG )
-  {
-    DO_S45ROUND
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SLOOP[]:      Set LOOP variable                                       */
-  /* Opcode range: 0x17                                                    */
-  /* Stack:        int32? -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SLOOP( INS_ARG )
-  {
-    DO_SLOOP
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SMD[]:        Set Minimum Distance                                    */
-  /* Opcode range: 0x1A                                                    */
-  /* Stack:        f26.6 -->                                               */
-  /*                                                                       */
-  static void
-  Ins_SMD( INS_ARG )
-  {
-    DO_SMD
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SCVTCI[]:     Set Control Value Table Cut In                          */
-  /* Opcode range: 0x1D                                                    */
-  /* Stack:        f26.6 -->                                               */
-  /*                                                                       */
-  static void
-  Ins_SCVTCI( INS_ARG )
-  {
-    DO_SCVTCI
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SSWCI[]:      Set Single Width Cut In                                 */
-  /* Opcode range: 0x1E                                                    */
-  /* Stack:        f26.6 -->                                               */
-  /*                                                                       */
-  static void
-  Ins_SSWCI( INS_ARG )
-  {
-    DO_SSWCI
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SSW[]:        Set Single Width                                        */
-  /* Opcode range: 0x1F                                                    */
-  /* Stack:        int32? -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SSW( INS_ARG )
-  {
-    DO_SSW
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* FLIPON[]:     Set auto-FLIP to ON                                     */
-  /* Opcode range: 0x4D                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_FLIPON( INS_ARG )
-  {
-    DO_FLIPON
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* FLIPOFF[]:    Set auto-FLIP to OFF                                    */
-  /* Opcode range: 0x4E                                                    */
-  /* Stack: -->                                                            */
-  /*                                                                       */
-  static void
-  Ins_FLIPOFF( INS_ARG )
-  {
-    DO_FLIPOFF
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SANGW[]:      Set ANGle Weight                                        */
-  /* Opcode range: 0x7E                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SANGW( INS_ARG )
-  {
-    /* instruction not supported anymore */
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SDB[]:        Set Delta Base                                          */
-  /* Opcode range: 0x5E                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SDB( INS_ARG )
-  {
-    DO_SDB
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* SDS[]:        Set Delta Shift                                         */
-  /* Opcode range: 0x5F                                                    */
-  /* Stack:        uint32 -->                                              */
-  /*                                                                       */
-  static void
-  Ins_SDS( INS_ARG )
-  {
-    DO_SDS
-  }
+#define ARRAY_BOUND_ERROR                         \
+    do                                            \
+    {                                             \
+      exc->error = FT_THROW( Invalid_Reference ); \
+      return;                                     \
+    } while (0)
 
 
   /*************************************************************************/
@@ -3839,9 +2627,10 @@
   /* Stack:        --> Euint16                                             */
   /*                                                                       */
   static void
-  Ins_MPPEM( INS_ARG )
+  Ins_MPPEM( TT_ExecContext  exc,
+             FT_Long*        args )
   {
-    DO_MPPEM
+    args[0] = exc->func_cur_ppem( exc );
   }
 
 
@@ -3852,22 +2641,29 @@
   /* Stack:        --> Euint16                                             */
   /*                                                                       */
   static void
-  Ins_MPS( INS_ARG )
+  Ins_MPS( TT_ExecContext  exc,
+           FT_Long*        args )
   {
-    DO_MPS
+    /* 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
   }
 
 
   /*************************************************************************/
   /*                                                                       */
-  /* DUP[]:        DUPlicate the top stack's element                       */
+  /* DUP[]:        DUPlicate the stack's top element                       */
   /* Opcode range: 0x20                                                    */
   /* Stack:        StkElt --> StkElt StkElt                                */
   /*                                                                       */
   static void
-  Ins_DUP( INS_ARG )
+  Ins_DUP( FT_Long*  args )
   {
-    DO_DUP
+    args[1] = args[0];
   }
 
 
@@ -3878,7 +2674,7 @@
   /* Stack:        StkElt -->                                              */
   /*                                                                       */
   static void
-  Ins_POP( INS_ARG )
+  Ins_POP( void )
   {
     /* nothing to do */
   }
@@ -3891,9 +2687,9 @@
   /* Stack:        StkElt... -->                                           */
   /*                                                                       */
   static void
-  Ins_CLEAR( INS_ARG )
+  Ins_CLEAR( TT_ExecContext  exc )
   {
-    DO_CLEAR
+    exc->new_top = 0;
   }
 
 
@@ -3904,9 +2700,14 @@
   /* Stack:        2 * StkElt --> 2 * StkElt                               */
   /*                                                                       */
   static void
-  Ins_SWAP( INS_ARG )
+  Ins_SWAP( FT_Long*  args )
   {
-    DO_SWAP
+    FT_Long  L;
+
+
+    L       = args[0];
+    args[0] = args[1];
+    args[1] = L;
   }
 
 
@@ -3917,74 +2718,10 @@
   /* Stack:        --> uint32                                              */
   /*                                                                       */
   static void
-  Ins_DEPTH( INS_ARG )
+  Ins_DEPTH( TT_ExecContext  exc,
+             FT_Long*        args )
   {
-    DO_DEPTH
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* CINDEX[]:     Copy INDEXed element                                    */
-  /* Opcode range: 0x25                                                    */
-  /* Stack:        int32 --> StkElt                                        */
-  /*                                                                       */
-  static void
-  Ins_CINDEX( INS_ARG )
-  {
-    DO_CINDEX
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* EIF[]:        End IF                                                  */
-  /* Opcode range: 0x59                                                    */
-  /* Stack:        -->                                                     */
-  /*                                                                       */
-  static void
-  Ins_EIF( INS_ARG )
-  {
-    /* nothing to do */
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* JROT[]:       Jump Relative On True                                   */
-  /* Opcode range: 0x78                                                    */
-  /* Stack:        StkElt int32 -->                                        */
-  /*                                                                       */
-  static void
-  Ins_JROT( INS_ARG )
-  {
-    DO_JROT
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* JMPR[]:       JuMP Relative                                           */
-  /* Opcode range: 0x1C                                                    */
-  /* Stack:        int32 -->                                               */
-  /*                                                                       */
-  static void
-  Ins_JMPR( INS_ARG )
-  {
-    DO_JMPR
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* JROF[]:       Jump Relative On False                                  */
-  /* Opcode range: 0x79                                                    */
-  /* Stack:        StkElt int32 -->                                        */
-  /*                                                                       */
-  static void
-  Ins_JROF( INS_ARG )
-  {
-    DO_JROF
+    args[0] = exc->top;
   }
 
 
@@ -3995,9 +2732,9 @@
   /* Stack:        int32? int32? --> bool                                  */
   /*                                                                       */
   static void
-  Ins_LT( INS_ARG )
+  Ins_LT( FT_Long*  args )
   {
-    DO_LT
+    args[0] = ( args[0] < args[1] );
   }
 
 
@@ -4008,9 +2745,9 @@
   /* Stack:        int32? int32? --> bool                                  */
   /*                                                                       */
   static void
-  Ins_LTEQ( INS_ARG )
+  Ins_LTEQ( FT_Long*  args )
   {
-    DO_LTEQ
+    args[0] = ( args[0] <= args[1] );
   }
 
 
@@ -4021,9 +2758,9 @@
   /* Stack:        int32? int32? --> bool                                  */
   /*                                                                       */
   static void
-  Ins_GT( INS_ARG )
+  Ins_GT( FT_Long*  args )
   {
-    DO_GT
+    args[0] = ( args[0] > args[1] );
   }
 
 
@@ -4034,9 +2771,9 @@
   /* Stack:        int32? int32? --> bool                                  */
   /*                                                                       */
   static void
-  Ins_GTEQ( INS_ARG )
+  Ins_GTEQ( FT_Long*  args )
   {
-    DO_GTEQ
+    args[0] = ( args[0] >= args[1] );
   }
 
 
@@ -4047,9 +2784,9 @@
   /* Stack:        StkElt StkElt --> bool                                  */
   /*                                                                       */
   static void
-  Ins_EQ( INS_ARG )
+  Ins_EQ( FT_Long*  args )
   {
-    DO_EQ
+    args[0] = ( args[0] == args[1] );
   }
 
 
@@ -4060,9 +2797,9 @@
   /* Stack:        StkElt StkElt --> bool                                  */
   /*                                                                       */
   static void
-  Ins_NEQ( INS_ARG )
+  Ins_NEQ( FT_Long*  args )
   {
-    DO_NEQ
+    args[0] = ( args[0] != args[1] );
   }
 
 
@@ -4073,9 +2810,10 @@
   /* Stack:        f26.6 --> bool                                          */
   /*                                                                       */
   static void
-  Ins_ODD( INS_ARG )
+  Ins_ODD( TT_ExecContext  exc,
+           FT_Long*        args )
   {
-    DO_ODD
+    args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 64 );
   }
 
 
@@ -4086,9 +2824,10 @@
   /* Stack:        f26.6 --> bool                                          */
   /*                                                                       */
   static void
-  Ins_EVEN( INS_ARG )
+  Ins_EVEN( TT_ExecContext  exc,
+            FT_Long*        args )
   {
-    DO_EVEN
+    args[0] = ( ( exc->func_round( exc, args[0], 0 ) & 127 ) == 0 );
   }
 
 
@@ -4099,9 +2838,9 @@
   /* Stack:        uint32 uint32 --> uint32                                */
   /*                                                                       */
   static void
-  Ins_AND( INS_ARG )
+  Ins_AND( FT_Long*  args )
   {
-    DO_AND
+    args[0] = ( args[0] && args[1] );
   }
 
 
@@ -4112,9 +2851,9 @@
   /* Stack:        uint32 uint32 --> uint32                                */
   /*                                                                       */
   static void
-  Ins_OR( INS_ARG )
+  Ins_OR( FT_Long*  args )
   {
-    DO_OR
+    args[0] = ( args[0] || args[1] );
   }
 
 
@@ -4125,9 +2864,9 @@
   /* Stack:        StkElt --> uint32                                       */
   /*                                                                       */
   static void
-  Ins_NOT( INS_ARG )
+  Ins_NOT( FT_Long*  args )
   {
-    DO_NOT
+    args[0] = !args[0];
   }
 
 
@@ -4138,9 +2877,9 @@
   /* Stack:        f26.6 f26.6 --> f26.6                                   */
   /*                                                                       */
   static void
-  Ins_ADD( INS_ARG )
+  Ins_ADD( FT_Long*  args )
   {
-    DO_ADD
+    args[0] += args[1];
   }
 
 
@@ -4151,9 +2890,9 @@
   /* Stack:        f26.6 f26.6 --> f26.6                                   */
   /*                                                                       */
   static void
-  Ins_SUB( INS_ARG )
+  Ins_SUB( FT_Long*  args )
   {
-    DO_SUB
+    args[0] -= args[1];
   }
 
 
@@ -4164,9 +2903,13 @@
   /* Stack:        f26.6 f26.6 --> f26.6                                   */
   /*                                                                       */
   static void
-  Ins_DIV( INS_ARG )
+  Ins_DIV( TT_ExecContext  exc,
+           FT_Long*        args )
   {
-    DO_DIV
+    if ( args[1] == 0 )
+      exc->error = FT_THROW( Divide_By_Zero );
+    else
+      args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] );
   }
 
 
@@ -4177,9 +2920,9 @@
   /* Stack:        f26.6 f26.6 --> f26.6                                   */
   /*                                                                       */
   static void
-  Ins_MUL( INS_ARG )
+  Ins_MUL( FT_Long*  args )
   {
-    DO_MUL
+    args[0] = FT_MulDiv( args[0], args[1], 64L );
   }
 
 
@@ -4190,9 +2933,9 @@
   /* Stack:        f26.6 --> f26.6                                         */
   /*                                                                       */
   static void
-  Ins_ABS( INS_ARG )
+  Ins_ABS( FT_Long*  args )
   {
-    DO_ABS
+    args[0] = FT_ABS( args[0] );
   }
 
 
@@ -4203,9 +2946,9 @@
   /* Stack: f26.6 --> f26.6                                                */
   /*                                                                       */
   static void
-  Ins_NEG( INS_ARG )
+  Ins_NEG( FT_Long*  args )
   {
-    DO_NEG
+    args[0] = -args[0];
   }
 
 
@@ -4216,9 +2959,9 @@
   /* Stack:        f26.6 --> f26.6                                         */
   /*                                                                       */
   static void
-  Ins_FLOOR( INS_ARG )
+  Ins_FLOOR( FT_Long*  args )
   {
-    DO_FLOOR
+    args[0] = FT_PIX_FLOOR( args[0] );
   }
 
 
@@ -4229,9 +2972,9 @@
   /* Stack:        f26.6 --> f26.6                                         */
   /*                                                                       */
   static void
-  Ins_CEILING( INS_ARG )
+  Ins_CEILING( FT_Long*  args )
   {
-    DO_CEILING
+    args[0] = FT_PIX_CEIL( args[0] );
   }
 
 
@@ -4242,9 +2985,59 @@
   /* Stack:        uint32 --> uint32                                       */
   /*                                                                       */
   static void
-  Ins_RS( INS_ARG )
+  Ins_RS( TT_ExecContext  exc,
+          FT_Long*        args )
   {
-    DO_RS
+#ifdef 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
+    {
+      /* subpixel hinting - avoid Typeman Dstroke and */
+      /* IStroke and Vacuform rounds                  */
+      if ( SUBPIXEL_HINTING                            &&
+           exc->ignore_x_mode                          &&
+           ( ( I == 24                             &&
+               ( exc->face->sph_found_func_flags &
+                 ( SPH_FDEF_SPACING_1 |
+                   SPH_FDEF_SPACING_2 )          ) ) ||
+             ( I == 22                      &&
+               ( exc->sph_in_func_flags   &
+                 SPH_FDEF_TYPEMAN_STROKES ) )        ||
+             ( I == 8                              &&
+               ( exc->face->sph_found_func_flags &
+                 SPH_FDEF_VACUFORM_ROUND_1       ) &&
+               exc->iup_called                     ) ) )
+        args[0] = 0;
+      else
+        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 */
   }
 
 
@@ -4255,9 +3048,19 @@
   /* Stack:        uint32 uint32 -->                                       */
   /*                                                                       */
   static void
-  Ins_WS( INS_ARG )
+  Ins_WS( TT_ExecContext  exc,
+          FT_Long*        args )
   {
-    DO_WS
+    FT_ULong  I = (FT_ULong)args[0];
+
+
+    if ( BOUNDSL( I, exc->storeSize ) )
+    {
+      if ( exc->pedantic_hinting )
+        ARRAY_BOUND_ERROR;
+    }
+    else
+      exc->storage[I] = args[1];
   }
 
 
@@ -4268,9 +3071,19 @@
   /* Stack:        f26.6 uint32 -->                                        */
   /*                                                                       */
   static void
-  Ins_WCVTP( INS_ARG )
+  Ins_WCVTP( TT_ExecContext  exc,
+             FT_Long*        args )
   {
-    DO_WCVTP
+    FT_ULong  I = (FT_ULong)args[0];
+
+
+    if ( BOUNDSL( I, exc->cvtSize ) )
+    {
+      if ( exc->pedantic_hinting )
+        ARRAY_BOUND_ERROR;
+    }
+    else
+      exc->func_write_cvt( exc, I, args[1] );
   }
 
 
@@ -4281,9 +3094,19 @@
   /* Stack:        uint32 uint32 -->                                       */
   /*                                                                       */
   static void
-  Ins_WCVTF( INS_ARG )
+  Ins_WCVTF( TT_ExecContext  exc,
+             FT_Long*        args )
   {
-    DO_WCVTF
+    FT_ULong  I = (FT_ULong)args[0];
+
+
+    if ( BOUNDSL( I, exc->cvtSize ) )
+    {
+      if ( exc->pedantic_hinting )
+        ARRAY_BOUND_ERROR;
+    }
+    else
+      exc->cvt[I] = FT_MulFix( args[1], exc->tt_metrics.scale );
   }
 
 
@@ -4294,9 +3117,21 @@
   /* Stack:        uint32 --> f26.6                                        */
   /*                                                                       */
   static void
-  Ins_RCVT( INS_ARG )
+  Ins_RCVT( TT_ExecContext  exc,
+            FT_Long*        args )
   {
-    DO_RCVT
+    FT_ULong  I = (FT_ULong)args[0];
+
+
+    if ( BOUNDSL( I, exc->cvtSize ) )
+    {
+      if ( exc->pedantic_hinting )
+        ARRAY_BOUND_ERROR;
+      else
+        args[0] = 0;
+    }
+    else
+      args[0] = exc->func_read_cvt( exc, I );
   }
 
 
@@ -4307,7 +3142,7 @@
   /* Stack:        uint32 -->                                              */
   /*                                                                       */
   static void
-  Ins_AA( INS_ARG )
+  Ins_AA( void )
   {
     /* intentionally no longer supported */
   }
@@ -4322,9 +3157,9 @@
   /* Note: The original instruction pops a value from the stack.           */
   /*                                                                       */
   static void
-  Ins_DEBUG( INS_ARG )
+  Ins_DEBUG( TT_ExecContext  exc )
   {
-    DO_DEBUG
+    exc->error = FT_THROW( Debug_OpCode );
   }
 
 
@@ -4335,9 +3170,13 @@
   /* Stack:        f26.6 --> f26.6                                         */
   /*                                                                       */
   static void
-  Ins_ROUND( INS_ARG )
+  Ins_ROUND( TT_ExecContext  exc,
+             FT_Long*        args )
   {
-    DO_ROUND
+    args[0] = exc->func_round(
+                exc,
+                args[0],
+                exc->tt_metrics.compensations[exc->opcode - 0x68] );
   }
 
 
@@ -4348,9 +3187,13 @@
   /* Stack:        f26.6 --> f26.6                                         */
   /*                                                                       */
   static void
-  Ins_NROUND( INS_ARG )
+  Ins_NROUND( TT_ExecContext  exc,
+              FT_Long*        args )
   {
-    DO_NROUND
+    args[0] = Round_None(
+                exc,
+                args[0],
+                exc->tt_metrics.compensations[exc->opcode - 0x6C] );
   }
 
 
@@ -4361,9 +3204,10 @@
   /* Stack:        int32? int32? --> int32                                 */
   /*                                                                       */
   static void
-  Ins_MAX( INS_ARG )
+  Ins_MAX( FT_Long*  args )
   {
-    DO_MAX
+    if ( args[1] > args[0] )
+      args[0] = args[1];
   }
 
 
@@ -4374,22 +3218,13 @@
   /* Stack:        int32? int32? --> int32                                 */
   /*                                                                       */
   static void
-  Ins_MIN( INS_ARG )
+  Ins_MIN( FT_Long*  args )
   {
-    DO_MIN
+    if ( args[1] < args[0] )
+      args[0] = args[1];
   }
 
 
-#endif  /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The following functions are called as is within the switch statement. */
-  /*                                                                       */
-  /*************************************************************************/
-
-
   /*************************************************************************/
   /*                                                                       */
   /* MINDEX[]:     Move INDEXed element                                    */
@@ -4397,44 +3232,69 @@
   /* Stack:        int32? --> StkElt                                       */
   /*                                                                       */
   static void
-  Ins_MINDEX( INS_ARG )
+  Ins_MINDEX( TT_ExecContext  exc,
+              FT_Long*        args )
   {
     FT_Long  L, K;
 
 
     L = args[0];
 
-    if ( L <= 0 || L > CUR.args )
+    if ( L <= 0 || L > exc->args )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
     }
     else
     {
-      K = CUR.stack[CUR.args - L];
+      K = exc->stack[exc->args - L];
 
-      FT_ARRAY_MOVE( &CUR.stack[CUR.args - L    ],
-                     &CUR.stack[CUR.args - L + 1],
+      FT_ARRAY_MOVE( &exc->stack[exc->args - L    ],
+                     &exc->stack[exc->args - L + 1],
                      ( L - 1 ) );
 
-      CUR.stack[CUR.args - 1] = K;
+      exc->stack[exc->args - 1] = K;
     }
   }
 
 
   /*************************************************************************/
   /*                                                                       */
+  /* CINDEX[]:     Copy INDEXed element                                    */
+  /* Opcode range: 0x25                                                    */
+  /* Stack:        int32 --> StkElt                                        */
+  /*                                                                       */
+  static void
+  Ins_CINDEX( TT_ExecContext  exc,
+              FT_Long*        args )
+  {
+    FT_Long  L;
+
+
+    L = args[0];
+
+    if ( L <= 0 || L > exc->args )
+    {
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
+      args[0] = 0;
+    }
+    else
+      args[0] = exc->stack[exc->args - L];
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
   /* ROLL[]:       ROLL top three elements                                 */
   /* Opcode range: 0x8A                                                    */
   /* Stack:        3 * StkElt --> 3 * StkElt                               */
   /*                                                                       */
   static void
-  Ins_ROLL( INS_ARG )
+  Ins_ROLL( FT_Long*  args )
   {
     FT_Long  A, B, C;
 
-    FT_UNUSED_EXEC;
-
 
     A = args[2];
     B = args[1];
@@ -4450,34 +3310,49 @@
   /*                                                                       */
   /* MANAGING THE FLOW OF CONTROL                                          */
   /*                                                                       */
-  /*   Instructions appear in the specification's order.                   */
-  /*                                                                       */
   /*************************************************************************/
 
 
-  static FT_Bool
-  SkipCode( EXEC_OP )
+  /*************************************************************************/
+  /*                                                                       */
+  /* SLOOP[]:      Set LOOP variable                                       */
+  /* Opcode range: 0x17                                                    */
+  /* Stack:        int32? -->                                              */
+  /*                                                                       */
+  static void
+  Ins_SLOOP( TT_ExecContext  exc,
+             FT_Long*        args )
   {
-    CUR.IP += CUR.length;
+    if ( args[0] < 0 )
+      exc->error = FT_THROW( Bad_Argument );
+    else
+      exc->GS.loop = args[0];
+  }
 
-    if ( CUR.IP < CUR.codeSize )
+
+  static FT_Bool
+  SkipCode( TT_ExecContext  exc )
+  {
+    exc->IP += exc->length;
+
+    if ( exc->IP < exc->codeSize )
     {
-      CUR.opcode = CUR.code[CUR.IP];
+      exc->opcode = exc->code[exc->IP];
 
-      CUR.length = opcode_length[CUR.opcode];
-      if ( CUR.length < 0 )
+      exc->length = opcode_length[exc->opcode];
+      if ( exc->length < 0 )
       {
-        if ( CUR.IP + 1 >= CUR.codeSize )
+        if ( exc->IP + 1 >= exc->codeSize )
           goto Fail_Overflow;
-        CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];
+        exc->length = 2 - exc->length * exc->code[exc->IP + 1];
       }
 
-      if ( CUR.IP + CUR.length <= CUR.codeSize )
+      if ( exc->IP + exc->length <= exc->codeSize )
         return SUCCESS;
     }
 
   Fail_Overflow:
-    CUR.error = FT_THROW( Code_Overflow );
+    exc->error = FT_THROW( Code_Overflow );
     return FAILURE;
   }
 
@@ -4489,7 +3364,8 @@
   /* Stack:        StkElt -->                                              */
   /*                                                                       */
   static void
-  Ins_IF( INS_ARG )
+  Ins_IF( TT_ExecContext  exc,
+          FT_Long*        args )
   {
     FT_Int   nIfs;
     FT_Bool  Out;
@@ -4503,10 +3379,10 @@
 
     do
     {
-      if ( SKIP_Code() == FAILURE )
+      if ( SkipCode( exc ) == FAILURE )
         return;
 
-      switch ( CUR.opcode )
+      switch ( exc->opcode )
       {
       case 0x58:      /* IF */
         nIfs++;
@@ -4532,21 +3408,19 @@
   /* Stack:        -->                                                     */
   /*                                                                       */
   static void
-  Ins_ELSE( INS_ARG )
+  Ins_ELSE( TT_ExecContext  exc )
   {
     FT_Int  nIfs;
 
-    FT_UNUSED_ARG;
-
 
     nIfs = 1;
 
     do
     {
-      if ( SKIP_Code() == FAILURE )
+      if ( SkipCode( exc ) == FAILURE )
         return;
 
-      switch ( CUR.opcode )
+      switch ( exc->opcode )
       {
       case 0x58:    /* IF */
         nIfs++;
@@ -4562,9 +3436,71 @@
 
   /*************************************************************************/
   /*                                                                       */
-  /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS                         */
+  /* EIF[]:        End IF                                                  */
+  /* Opcode range: 0x59                                                    */
+  /* Stack:        -->                                                     */
   /*                                                                       */
-  /*   Instructions appear in the specification's order.                   */
+  static void
+  Ins_EIF( void )
+  {
+    /* nothing to do */
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* JMPR[]:       JuMP Relative                                           */
+  /* Opcode range: 0x1C                                                    */
+  /* Stack:        int32 -->                                               */
+  /*                                                                       */
+  static void
+  Ins_JMPR( TT_ExecContext  exc,
+            FT_Long*        args )
+  {
+    if ( args[0] == 0 && exc->args == 0 )
+      exc->error = FT_THROW( Bad_Argument );
+    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 );
+    exc->step_ins = FALSE;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* JROT[]:       Jump Relative On True                                   */
+  /* Opcode range: 0x78                                                    */
+  /* Stack:        StkElt int32 -->                                        */
+  /*                                                                       */
+  static void
+  Ins_JROT( TT_ExecContext  exc,
+            FT_Long*        args )
+  {
+    if ( args[1] != 0 )
+      Ins_JMPR( exc, args );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* JROF[]:       Jump Relative On False                                  */
+  /* Opcode range: 0x79                                                    */
+  /* Stack:        StkElt int32 -->                                        */
+  /*                                                                       */
+  static void
+  Ins_JROF( TT_ExecContext  exc,
+            FT_Long*        args )
+  {
+    if ( args[1] == 0 )
+      Ins_JMPR( exc, args );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS                         */
   /*                                                                       */
   /*************************************************************************/
 
@@ -4576,7 +3512,8 @@
   /* Stack:        uint32 -->                                              */
   /*                                                                       */
   static void
-  Ins_FDEF( INS_ARG )
+  Ins_FDEF( TT_ExecContext  exc,
+            FT_Long*        args )
   {
     FT_ULong       n;
     TT_DefRecord*  rec;
@@ -4686,9 +3623,9 @@
     /* some font programs are broken enough to redefine functions! */
     /* We will then parse the current table.                       */
 
-    rec   = CUR.FDefs;
-    limit = rec + CUR.numFDefs;
-    n     = args[0];
+    rec   = exc->FDefs;
+    limit = rec + exc->numFDefs;
+    n     = (FT_ULong)args[0];
 
     for ( ; rec < limit; rec++ )
     {
@@ -4699,31 +3636,31 @@
     if ( rec == limit )
     {
       /* check that there is enough room for new functions */
-      if ( CUR.numFDefs >= CUR.maxFDefs )
+      if ( exc->numFDefs >= exc->maxFDefs )
       {
-        CUR.error = FT_THROW( Too_Many_Function_Defs );
+        exc->error = FT_THROW( Too_Many_Function_Defs );
         return;
       }
-      CUR.numFDefs++;
+      exc->numFDefs++;
     }
 
     /* Although FDEF takes unsigned 32-bit integer,  */
     /* func # must be within unsigned 16-bit integer */
     if ( n > 0xFFFFU )
     {
-      CUR.error = FT_THROW( Too_Many_Function_Defs );
+      exc->error = FT_THROW( Too_Many_Function_Defs );
       return;
     }
 
-    rec->range          = CUR.curRange;
+    rec->range          = exc->curRange;
     rec->opc            = (FT_UInt16)n;
-    rec->start          = CUR.IP + 1;
+    rec->start          = exc->IP + 1;
     rec->active         = TRUE;
     rec->inline_delta   = FALSE;
     rec->sph_fdef_flags = 0x0000;
 
-    if ( n > CUR.maxFunc )
-      CUR.maxFunc = (FT_UInt16)n;
+    if ( n > exc->maxFunc )
+      exc->maxFunc = (FT_UInt16)n;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     /* We don't know for sure these are typeman functions, */
@@ -4735,7 +3672,7 @@
     /* Now skip the whole function definition. */
     /* We don't allow nested IDEFS & FDEFs.    */
 
-    while ( SKIP_Code() == SUCCESS )
+    while ( SkipCode( exc ) == SUCCESS )
     {
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
@@ -4744,28 +3681,28 @@
       {
         for ( i = 0; i < opcode_patterns; i++ )
         {
-          if ( opcode_pointer[i] < opcode_size[i]                 &&
-               CUR.opcode == opcode_pattern[i][opcode_pointer[i]] )
+          if ( opcode_pointer[i] < opcode_size[i]                  &&
+               exc->opcode == opcode_pattern[i][opcode_pointer[i]] )
           {
             opcode_pointer[i] += 1;
 
             if ( opcode_pointer[i] == opcode_size[i] )
             {
-              FT_TRACE7(( "sph: Function %d, opcode ptrn: %d, %s %s\n",
+              FT_TRACE6(( "sph: Function %d, opcode ptrn: %d, %s %s\n",
                           i, n,
-                          CUR.face->root.family_name,
-                          CUR.face->root.style_name ));
+                          exc->face->root.family_name,
+                          exc->face->root.style_name ));
 
               switch ( i )
               {
               case 0:
-                rec->sph_fdef_flags            |= SPH_FDEF_INLINE_DELTA_1;
-                CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1;
+                rec->sph_fdef_flags             |= SPH_FDEF_INLINE_DELTA_1;
+                exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1;
                 break;
 
               case 1:
-                rec->sph_fdef_flags            |= SPH_FDEF_INLINE_DELTA_2;
-                CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2;
+                rec->sph_fdef_flags             |= SPH_FDEF_INLINE_DELTA_2;
+                exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2;
                 break;
 
               case 2:
@@ -4773,8 +3710,8 @@
                 {
                   /* needs to be implemented still */
                 case 58:
-                  rec->sph_fdef_flags            |= SPH_FDEF_DIAGONAL_STROKE;
-                  CUR.face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE;
+                  rec->sph_fdef_flags             |= SPH_FDEF_DIAGONAL_STROKE;
+                  exc->face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE;
                 }
                 break;
 
@@ -4782,15 +3719,15 @@
                 switch ( n )
                 {
                 case 0:
-                  rec->sph_fdef_flags            |= SPH_FDEF_VACUFORM_ROUND_1;
-                  CUR.face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1;
+                  rec->sph_fdef_flags             |= SPH_FDEF_VACUFORM_ROUND_1;
+                  exc->face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1;
                 }
                 break;
 
               case 4:
                 /* probably not necessary to detect anymore */
-                rec->sph_fdef_flags            |= SPH_FDEF_TTFAUTOHINT_1;
-                CUR.face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1;
+                rec->sph_fdef_flags             |= SPH_FDEF_TTFAUTOHINT_1;
+                exc->face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1;
                 break;
 
               case 5:
@@ -4802,8 +3739,8 @@
                 case 4:
                 case 7:
                 case 8:
-                  rec->sph_fdef_flags            |= SPH_FDEF_SPACING_1;
-                  CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_1;
+                  rec->sph_fdef_flags             |= SPH_FDEF_SPACING_1;
+                  exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_1;
                 }
                 break;
 
@@ -4816,20 +3753,20 @@
                 case 4:
                 case 7:
                 case 8:
-                  rec->sph_fdef_flags            |= SPH_FDEF_SPACING_2;
-                  CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_2;
+                  rec->sph_fdef_flags             |= SPH_FDEF_SPACING_2;
+                  exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_2;
                 }
                 break;
 
                case 7:
-                 rec->sph_fdef_flags            |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
-                 CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+                 rec->sph_fdef_flags             |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+                 exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
                  break;
 
                case 8:
 #if 0
-                 rec->sph_fdef_flags            |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
-                 CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+                 rec->sph_fdef_flags             |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
+                 exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
 #endif
                  break;
               }
@@ -4842,22 +3779,22 @@
         }
 
         /* Set sph_compatibility_mode only when deltas are detected */
-        CUR.face->sph_compatibility_mode =
-          ( ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) |
-            ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
+        exc->face->sph_compatibility_mode =
+          ( ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) |
+            ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
       }
 
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-      switch ( CUR.opcode )
+      switch ( exc->opcode )
       {
       case 0x89:    /* IDEF */
       case 0x2C:    /* FDEF */
-        CUR.error = FT_THROW( Nested_DEFS );
+        exc->error = FT_THROW( Nested_DEFS );
         return;
 
       case 0x2D:   /* ENDF */
-        rec->end = CUR.IP;
+        rec->end = exc->IP;
         return;
       }
     }
@@ -4871,40 +3808,37 @@
   /* Stack:        -->                                                     */
   /*                                                                       */
   static void
-  Ins_ENDF( INS_ARG )
+  Ins_ENDF( TT_ExecContext  exc )
   {
     TT_CallRec*  pRec;
 
-    FT_UNUSED_ARG;
-
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    CUR.sph_in_func_flags = 0x0000;
+    exc->sph_in_func_flags = 0x0000;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-    if ( CUR.callTop <= 0 )     /* We encountered an ENDF without a call */
+    if ( exc->callTop <= 0 )     /* We encountered an ENDF without a call */
     {
-      CUR.error = FT_THROW( ENDF_In_Exec_Stream );
+      exc->error = FT_THROW( ENDF_In_Exec_Stream );
       return;
     }
 
-    CUR.callTop--;
+    exc->callTop--;
 
-    pRec = &CUR.callStack[CUR.callTop];
+    pRec = &exc->callStack[exc->callTop];
 
     pRec->Cur_Count--;
 
-    CUR.step_ins = FALSE;
+    exc->step_ins = FALSE;
 
     if ( pRec->Cur_Count > 0 )
     {
-      CUR.callTop++;
-      CUR.IP = pRec->Def->start;
+      exc->callTop++;
+      exc->IP = pRec->Def->start;
     }
     else
       /* Loop through the current function */
-      INS_Goto_CodeRange( pRec->Caller_Range,
-                          pRec->Caller_IP );
+      Ins_Goto_CodeRange( exc, pRec->Caller_Range, pRec->Caller_IP );
 
     /* Exit the current call frame.                      */
 
@@ -4923,7 +3857,8 @@
   /* Stack:        uint32? -->                                             */
   /*                                                                       */
   static void
-  Ins_CALL( INS_ARG )
+  Ins_CALL( TT_ExecContext  exc,
+            FT_Long*        args )
   {
     FT_ULong       F;
     TT_CallRec*    pCrec;
@@ -4932,28 +3867,28 @@
 
     /* first of all, check the index */
 
-    F = args[0];
-    if ( BOUNDSL( F, CUR.maxFunc + 1 ) )
+    F = (FT_ULong)args[0];
+    if ( BOUNDSL( F, exc->maxFunc + 1 ) )
       goto Fail;
 
     /* Except for some old Apple fonts, all functions in a TrueType */
     /* font are defined in increasing order, starting from 0.  This */
     /* means that we normally have                                  */
     /*                                                              */
-    /*    CUR.maxFunc+1 == CUR.numFDefs                             */
-    /*    CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc             */
+    /*    exc->maxFunc+1 == exc->numFDefs                           */
+    /*    exc->FDefs[n].opc == n for n in 0..exc->maxFunc           */
     /*                                                              */
     /* If this isn't true, we need to look up the function table.   */
 
-    def = CUR.FDefs + F;
-    if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F )
+    def = exc->FDefs + F;
+    if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
     {
       /* look up the FDefs table */
       TT_DefRecord*  limit;
 
 
-      def   = CUR.FDefs;
-      limit = def + CUR.numFDefs;
+      def   = exc->FDefs;
+      limit = def + exc->numFDefs;
 
       while ( def < limit && def->opc != F )
         def++;
@@ -4967,41 +3902,40 @@
       goto Fail;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                              &&
-         CUR.ignore_x_mode                                             &&
-         ( ( CUR.iup_called                                        &&
-             ( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
-           ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 )       ) )
+    if ( SUBPIXEL_HINTING                                               &&
+         exc->ignore_x_mode                                             &&
+         ( ( exc->iup_called                                        &&
+             ( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
+           ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 )        ) )
       goto Fail;
     else
-      CUR.sph_in_func_flags = def->sph_fdef_flags;
+      exc->sph_in_func_flags = def->sph_fdef_flags;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
     /* check the call stack */
-    if ( CUR.callTop >= CUR.callSize )
+    if ( exc->callTop >= exc->callSize )
     {
-      CUR.error = FT_THROW( Stack_Overflow );
+      exc->error = FT_THROW( Stack_Overflow );
       return;
     }
 
-    pCrec = CUR.callStack + CUR.callTop;
+    pCrec = exc->callStack + exc->callTop;
 
-    pCrec->Caller_Range = CUR.curRange;
-    pCrec->Caller_IP    = CUR.IP + 1;
+    pCrec->Caller_Range = exc->curRange;
+    pCrec->Caller_IP    = exc->IP + 1;
     pCrec->Cur_Count    = 1;
     pCrec->Def          = def;
 
-    CUR.callTop++;
+    exc->callTop++;
 
-    INS_Goto_CodeRange( def->range,
-                        def->start );
+    Ins_Goto_CodeRange( exc, def->range, def->start );
 
-    CUR.step_ins = FALSE;
+    exc->step_ins = FALSE;
 
     return;
 
   Fail:
-    CUR.error = FT_THROW( Invalid_Reference );
+    exc->error = FT_THROW( Invalid_Reference );
   }
 
 
@@ -5012,7 +3946,8 @@
   /* Stack:        uint32? Eint16? -->                                     */
   /*                                                                       */
   static void
-  Ins_LOOPCALL( INS_ARG )
+  Ins_LOOPCALL( TT_ExecContext  exc,
+                FT_Long*        args )
   {
     FT_ULong       F;
     TT_CallRec*    pCrec;
@@ -5020,28 +3955,28 @@
 
 
     /* first of all, check the index */
-    F = args[1];
-    if ( BOUNDSL( F, CUR.maxFunc + 1 ) )
+    F = (FT_ULong)args[1];
+    if ( BOUNDSL( F, exc->maxFunc + 1 ) )
       goto Fail;
 
     /* Except for some old Apple fonts, all functions in a TrueType */
     /* font are defined in increasing order, starting from 0.  This */
     /* means that we normally have                                  */
     /*                                                              */
-    /*    CUR.maxFunc+1 == CUR.numFDefs                             */
-    /*    CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc             */
+    /*    exc->maxFunc+1 == exc->numFDefs                           */
+    /*    exc->FDefs[n].opc == n for n in 0..exc->maxFunc           */
     /*                                                              */
     /* If this isn't true, we need to look up the function table.   */
 
-    def = CUR.FDefs + F;
-    if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F )
+    def = exc->FDefs + F;
+    if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
     {
       /* look up the FDefs table */
       TT_DefRecord*  limit;
 
 
-      def   = CUR.FDefs;
-      limit = def + CUR.numFDefs;
+      def   = exc->FDefs;
+      limit = def + exc->numFDefs;
 
       while ( def < limit && def->opc != F )
         def++;
@@ -5056,40 +3991,40 @@
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     if ( SUBPIXEL_HINTING                                    &&
-         CUR.ignore_x_mode                                   &&
+         exc->ignore_x_mode                                  &&
          ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
       goto Fail;
     else
-      CUR.sph_in_func_flags = def->sph_fdef_flags;
+      exc->sph_in_func_flags = def->sph_fdef_flags;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
     /* check stack */
-    if ( CUR.callTop >= CUR.callSize )
+    if ( exc->callTop >= exc->callSize )
     {
-      CUR.error = FT_THROW( Stack_Overflow );
+      exc->error = FT_THROW( Stack_Overflow );
       return;
     }
 
     if ( args[0] > 0 )
     {
-      pCrec = CUR.callStack + CUR.callTop;
+      pCrec = exc->callStack + exc->callTop;
 
-      pCrec->Caller_Range = CUR.curRange;
-      pCrec->Caller_IP    = CUR.IP + 1;
+      pCrec->Caller_Range = exc->curRange;
+      pCrec->Caller_IP    = exc->IP + 1;
       pCrec->Cur_Count    = (FT_Int)args[0];
       pCrec->Def          = def;
 
-      CUR.callTop++;
+      exc->callTop++;
 
-      INS_Goto_CodeRange( def->range, def->start );
+      Ins_Goto_CodeRange( exc, def->range, def->start );
 
-      CUR.step_ins = FALSE;
+      exc->step_ins = FALSE;
     }
 
     return;
 
   Fail:
-    CUR.error = FT_THROW( Invalid_Reference );
+    exc->error = FT_THROW( Invalid_Reference );
   }
 
 
@@ -5100,7 +4035,8 @@
   /* Stack:        Eint8 -->                                               */
   /*                                                                       */
   static void
-  Ins_IDEF( INS_ARG )
+  Ins_IDEF( TT_ExecContext  exc,
+            FT_Long*        args )
   {
     TT_DefRecord*  def;
     TT_DefRecord*  limit;
@@ -5108,8 +4044,8 @@
 
     /*  First of all, look for the same function in our table */
 
-    def   = CUR.IDefs;
-    limit = def + CUR.numIDefs;
+    def   = exc->IDefs;
+    limit = def + exc->numIDefs;
 
     for ( ; def < limit; def++ )
       if ( def->opc == (FT_ULong)args[0] )
@@ -5118,39 +4054,39 @@
     if ( def == limit )
     {
       /* check that there is enough room for a new instruction */
-      if ( CUR.numIDefs >= CUR.maxIDefs )
+      if ( exc->numIDefs >= exc->maxIDefs )
       {
-        CUR.error = FT_THROW( Too_Many_Instruction_Defs );
+        exc->error = FT_THROW( Too_Many_Instruction_Defs );
         return;
       }
-      CUR.numIDefs++;
+      exc->numIDefs++;
     }
 
     /* opcode must be unsigned 8-bit integer */
     if ( 0 > args[0] || args[0] > 0x00FF )
     {
-      CUR.error = FT_THROW( Too_Many_Instruction_Defs );
+      exc->error = FT_THROW( Too_Many_Instruction_Defs );
       return;
     }
 
     def->opc    = (FT_Byte)args[0];
-    def->start  = CUR.IP + 1;
-    def->range  = CUR.curRange;
+    def->start  = exc->IP + 1;
+    def->range  = exc->curRange;
     def->active = TRUE;
 
-    if ( (FT_ULong)args[0] > CUR.maxIns )
-      CUR.maxIns = (FT_Byte)args[0];
+    if ( (FT_ULong)args[0] > exc->maxIns )
+      exc->maxIns = (FT_Byte)args[0];
 
     /* Now skip the whole function definition. */
     /* We don't allow nested IDEFs & FDEFs.    */
 
-    while ( SKIP_Code() == SUCCESS )
+    while ( SkipCode( exc ) == SUCCESS )
     {
-      switch ( CUR.opcode )
+      switch ( exc->opcode )
       {
       case 0x89:   /* IDEF */
       case 0x2C:   /* FDEF */
-        CUR.error = FT_THROW( Nested_DEFS );
+        exc->error = FT_THROW( Nested_DEFS );
         return;
       case 0x2D:   /* ENDF */
         return;
@@ -5163,8 +4099,6 @@
   /*                                                                       */
   /* PUSHING DATA ONTO THE INTERPRETER STACK                               */
   /*                                                                       */
-  /*   Instructions appear in the specification's order.                   */
-  /*                                                                       */
   /*************************************************************************/
 
 
@@ -5175,23 +4109,24 @@
   /* Stack:        --> uint32...                                           */
   /*                                                                       */
   static void
-  Ins_NPUSHB( INS_ARG )
+  Ins_NPUSHB( TT_ExecContext  exc,
+              FT_Long*        args )
   {
     FT_UShort  L, K;
 
 
-    L = (FT_UShort)CUR.code[CUR.IP + 1];
+    L = (FT_UShort)exc->code[exc->IP + 1];
 
-    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+    if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
     {
-      CUR.error = FT_THROW( Stack_Overflow );
+      exc->error = FT_THROW( Stack_Overflow );
       return;
     }
 
     for ( K = 1; K <= L; K++ )
-      args[K - 1] = CUR.code[CUR.IP + K + 1];
+      args[K - 1] = exc->code[exc->IP + K + 1];
 
-    CUR.new_top += L;
+    exc->new_top += L;
   }
 
 
@@ -5202,26 +4137,27 @@
   /* Stack:        --> int32...                                            */
   /*                                                                       */
   static void
-  Ins_NPUSHW( INS_ARG )
+  Ins_NPUSHW( TT_ExecContext  exc,
+              FT_Long*        args )
   {
     FT_UShort  L, K;
 
 
-    L = (FT_UShort)CUR.code[CUR.IP + 1];
+    L = (FT_UShort)exc->code[exc->IP + 1];
 
-    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+    if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
     {
-      CUR.error = FT_THROW( Stack_Overflow );
+      exc->error = FT_THROW( Stack_Overflow );
       return;
     }
 
-    CUR.IP += 2;
+    exc->IP += 2;
 
     for ( K = 0; K < L; K++ )
-      args[K] = GET_ShortIns();
+      args[K] = GetShortIns( exc );
 
-    CUR.step_ins = FALSE;
-    CUR.new_top += L;
+    exc->step_ins = FALSE;
+    exc->new_top += L;
   }
 
 
@@ -5232,21 +4168,22 @@
   /* Stack:        --> uint32...                                           */
   /*                                                                       */
   static void
-  Ins_PUSHB( INS_ARG )
+  Ins_PUSHB( TT_ExecContext  exc,
+             FT_Long*        args )
   {
     FT_UShort  L, K;
 
 
-    L = (FT_UShort)( CUR.opcode - 0xB0 + 1 );
+    L = (FT_UShort)( exc->opcode - 0xB0 + 1 );
 
-    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+    if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
     {
-      CUR.error = FT_THROW( Stack_Overflow );
+      exc->error = FT_THROW( Stack_Overflow );
       return;
     }
 
     for ( K = 1; K <= L; K++ )
-      args[K - 1] = CUR.code[CUR.IP + K];
+      args[K - 1] = exc->code[exc->IP + K];
   }
 
 
@@ -5257,25 +4194,26 @@
   /* Stack:        --> int32...                                            */
   /*                                                                       */
   static void
-  Ins_PUSHW( INS_ARG )
+  Ins_PUSHW( TT_ExecContext  exc,
+             FT_Long*        args )
   {
     FT_UShort  L, K;
 
 
-    L = (FT_UShort)( CUR.opcode - 0xB8 + 1 );
+    L = (FT_UShort)( exc->opcode - 0xB8 + 1 );
 
-    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+    if ( BOUNDS( L, exc->stackSize + 1 - exc->top ) )
     {
-      CUR.error = FT_THROW( Stack_Overflow );
+      exc->error = FT_THROW( Stack_Overflow );
       return;
     }
 
-    CUR.IP++;
+    exc->IP++;
 
     for ( K = 0; K < L; K++ )
-      args[K] = GET_ShortIns();
+      args[K] = GetShortIns( exc );
 
-    CUR.step_ins = FALSE;
+    exc->step_ins = FALSE;
   }
 
 
@@ -5283,11 +4221,561 @@
   /*                                                                       */
   /* MANAGING THE GRAPHICS STATE                                           */
   /*                                                                       */
-  /*  Instructions appear in the specs' order.                             */
-  /*                                                                       */
   /*************************************************************************/
 
 
+  static FT_Bool
+  Ins_SxVTL( TT_ExecContext  exc,
+             FT_UShort       aIdx1,
+             FT_UShort       aIdx2,
+             FT_UnitVector*  Vec )
+  {
+    FT_Long     A, B, C;
+    FT_Vector*  p1;
+    FT_Vector*  p2;
+
+    FT_Byte  opcode = exc->opcode;
+
+
+    if ( BOUNDS( aIdx1, exc->zp2.n_points ) ||
+         BOUNDS( aIdx2, exc->zp1.n_points ) )
+    {
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
+      return FAILURE;
+    }
+
+    p1 = exc->zp1.cur + aIdx2;
+    p2 = exc->zp2.cur + aIdx1;
+
+    A = p1->x - p2->x;
+    B = p1->y - p2->y;
+
+    /* If p1 == p2, SPvTL and SFvTL behave the same as */
+    /* SPvTCA[X] and SFvTCA[X], respectively.          */
+    /*                                                 */
+    /* Confirmed by Greg Hitchcock.                    */
+
+    if ( A == 0 && B == 0 )
+    {
+      A      = 0x4000;
+      opcode = 0;
+    }
+
+    if ( ( opcode & 1 ) != 0 )
+    {
+      C =  B;   /* counter clockwise rotation */
+      B =  A;
+      A = -C;
+    }
+
+    Normalize( A, B, Vec );
+
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SVTCA[a]:     Set (F and P) Vectors to Coordinate Axis                */
+  /* Opcode range: 0x00-0x01                                               */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  /* SPvTCA[a]:    Set PVector to Coordinate Axis                          */
+  /* Opcode range: 0x02-0x03                                               */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  /* SFvTCA[a]:    Set FVector to Coordinate Axis                          */
+  /* Opcode range: 0x04-0x05                                               */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static void
+  Ins_SxyTCA( TT_ExecContext  exc )
+  {
+    FT_Short  AA, BB;
+
+    FT_Byte  opcode = exc->opcode;
+
+
+    AA = (FT_Short)( ( opcode & 1 ) << 14 );
+    BB = (FT_Short)( AA ^ 0x4000 );
+
+    if ( opcode < 4 )
+    {
+      exc->GS.projVector.x = AA;
+      exc->GS.projVector.y = BB;
+
+      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 );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SPvTL[a]:     Set PVector To Line                                     */
+  /* Opcode range: 0x06-0x07                                               */
+  /* Stack:        uint32 uint32 -->                                       */
+  /*                                                                       */
+  static void
+  Ins_SPVTL( TT_ExecContext  exc,
+             FT_Long*        args )
+  {
+    if ( Ins_SxVTL( exc,
+                    (FT_UShort)args[1],
+                    (FT_UShort)args[0],
+                    &exc->GS.projVector ) == SUCCESS )
+    {
+      exc->GS.dualVector = exc->GS.projVector;
+      GUESS_VECTOR( freeVector );
+      Compute_Funcs( exc );
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SFvTL[a]:     Set FVector To Line                                     */
+  /* Opcode range: 0x08-0x09                                               */
+  /* Stack:        uint32 uint32 -->                                       */
+  /*                                                                       */
+  static void
+  Ins_SFVTL( TT_ExecContext  exc,
+             FT_Long*        args )
+  {
+    if ( Ins_SxVTL( exc,
+                    (FT_UShort)args[1],
+                    (FT_UShort)args[0],
+                    &exc->GS.freeVector ) == SUCCESS )
+    {
+      GUESS_VECTOR( projVector );
+      Compute_Funcs( exc );
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SFvTPv[]:     Set FVector To PVector                                  */
+  /* Opcode range: 0x0E                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static void
+  Ins_SFVTPV( TT_ExecContext  exc )
+  {
+    GUESS_VECTOR( projVector );
+    exc->GS.freeVector = exc->GS.projVector;
+    Compute_Funcs( exc );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SPvFS[]:      Set PVector From Stack                                  */
+  /* Opcode range: 0x0A                                                    */
+  /* Stack:        f2.14 f2.14 -->                                         */
+  /*                                                                       */
+  static void
+  Ins_SPVFS( TT_ExecContext  exc,
+             FT_Long*        args )
+  {
+    FT_Short  S;
+    FT_Long   X, Y;
+
+
+    /* Only use low 16bits, then sign extend */
+    S = (FT_Short)args[1];
+    Y = (FT_Long)S;
+    S = (FT_Short)args[0];
+    X = (FT_Long)S;
+
+    Normalize( X, Y, &exc->GS.projVector );
+
+    exc->GS.dualVector = exc->GS.projVector;
+    GUESS_VECTOR( freeVector );
+    Compute_Funcs( exc );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SFvFS[]:      Set FVector From Stack                                  */
+  /* Opcode range: 0x0B                                                    */
+  /* Stack:        f2.14 f2.14 -->                                         */
+  /*                                                                       */
+  static void
+  Ins_SFVFS( TT_ExecContext  exc,
+             FT_Long*        args )
+  {
+    FT_Short  S;
+    FT_Long   X, Y;
+
+
+    /* Only use low 16bits, then sign extend */
+    S = (FT_Short)args[1];
+    Y = (FT_Long)S;
+    S = (FT_Short)args[0];
+    X = S;
+
+    Normalize( X, Y, &exc->GS.freeVector );
+    GUESS_VECTOR( projVector );
+    Compute_Funcs( exc );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GPv[]:        Get Projection Vector                                   */
+  /* Opcode range: 0x0C                                                    */
+  /* Stack:        ef2.14 --> ef2.14                                       */
+  /*                                                                       */
+  static void
+  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
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GFv[]:        Get Freedom Vector                                      */
+  /* Opcode range: 0x0D                                                    */
+  /* Stack:        ef2.14 --> ef2.14                                       */
+  /*                                                                       */
+  static void
+  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
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SRP0[]:       Set Reference Point 0                                   */
+  /* Opcode range: 0x10                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static void
+  Ins_SRP0( TT_ExecContext  exc,
+            FT_Long*        args )
+  {
+    exc->GS.rp0 = (FT_UShort)args[0];
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SRP1[]:       Set Reference Point 1                                   */
+  /* Opcode range: 0x11                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static void
+  Ins_SRP1( TT_ExecContext  exc,
+            FT_Long*        args )
+  {
+    exc->GS.rp1 = (FT_UShort)args[0];
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SRP2[]:       Set Reference Point 2                                   */
+  /* Opcode range: 0x12                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static void
+  Ins_SRP2( TT_ExecContext  exc,
+            FT_Long*        args )
+  {
+    exc->GS.rp2 = (FT_UShort)args[0];
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SMD[]:        Set Minimum Distance                                    */
+  /* Opcode range: 0x1A                                                    */
+  /* Stack:        f26.6 -->                                               */
+  /*                                                                       */
+  static void
+  Ins_SMD( TT_ExecContext  exc,
+           FT_Long*        args )
+  {
+    exc->GS.minimum_distance = args[0];
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SCVTCI[]:     Set Control Value Table Cut In                          */
+  /* Opcode range: 0x1D                                                    */
+  /* Stack:        f26.6 -->                                               */
+  /*                                                                       */
+  static void
+  Ins_SCVTCI( TT_ExecContext  exc,
+              FT_Long*        args )
+  {
+    exc->GS.control_value_cutin = (FT_F26Dot6)args[0];
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SSWCI[]:      Set Single Width Cut In                                 */
+  /* Opcode range: 0x1E                                                    */
+  /* Stack:        f26.6 -->                                               */
+  /*                                                                       */
+  static void
+  Ins_SSWCI( TT_ExecContext  exc,
+             FT_Long*        args )
+  {
+    exc->GS.single_width_cutin = (FT_F26Dot6)args[0];
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SSW[]:        Set Single Width                                        */
+  /* Opcode range: 0x1F                                                    */
+  /* Stack:        int32? -->                                              */
+  /*                                                                       */
+  static void
+  Ins_SSW( TT_ExecContext  exc,
+           FT_Long*        args )
+  {
+    exc->GS.single_width_value = FT_MulFix( args[0],
+                                            exc->tt_metrics.scale );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FLIPON[]:     Set auto-FLIP to ON                                     */
+  /* Opcode range: 0x4D                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static void
+  Ins_FLIPON( TT_ExecContext  exc )
+  {
+    exc->GS.auto_flip = TRUE;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FLIPOFF[]:    Set auto-FLIP to OFF                                    */
+  /* Opcode range: 0x4E                                                    */
+  /* Stack: -->                                                            */
+  /*                                                                       */
+  static void
+  Ins_FLIPOFF( TT_ExecContext  exc )
+  {
+    exc->GS.auto_flip = FALSE;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SANGW[]:      Set ANGle Weight                                        */
+  /* Opcode range: 0x7E                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static void
+  Ins_SANGW( void )
+  {
+    /* instruction not supported anymore */
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SDB[]:        Set Delta Base                                          */
+  /* Opcode range: 0x5E                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static void
+  Ins_SDB( TT_ExecContext  exc,
+           FT_Long*        args )
+  {
+    exc->GS.delta_base = (FT_UShort)args[0];
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SDS[]:        Set Delta Shift                                         */
+  /* Opcode range: 0x5F                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static void
+  Ins_SDS( TT_ExecContext  exc,
+           FT_Long*        args )
+  {
+    if ( (FT_ULong)args[0] > 6UL )
+      exc->error = FT_THROW( Bad_Argument );
+    else
+      exc->GS.delta_shift = (FT_UShort)args[0];
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* RTHG[]:       Round To Half Grid                                      */
+  /* Opcode range: 0x19                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static void
+  Ins_RTHG( TT_ExecContext  exc )
+  {
+    exc->GS.round_state = TT_Round_To_Half_Grid;
+    exc->func_round     = (TT_Round_Func)Round_To_Half_Grid;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* RTG[]:        Round To Grid                                           */
+  /* Opcode range: 0x18                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static void
+  Ins_RTG( TT_ExecContext  exc )
+  {
+    exc->GS.round_state = TT_Round_To_Grid;
+    exc->func_round     = (TT_Round_Func)Round_To_Grid;
+  }
+
+
+  /*************************************************************************/
+  /* RTDG[]:       Round To Double Grid                                    */
+  /* Opcode range: 0x3D                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static void
+  Ins_RTDG( TT_ExecContext  exc )
+  {
+    exc->GS.round_state = TT_Round_To_Double_Grid;
+    exc->func_round     = (TT_Round_Func)Round_To_Double_Grid;
+  }
+
+
+  /*************************************************************************/
+  /* RUTG[]:       Round Up To Grid                                        */
+  /* Opcode range: 0x7C                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static void
+  Ins_RUTG( TT_ExecContext  exc )
+  {
+    exc->GS.round_state = TT_Round_Up_To_Grid;
+    exc->func_round     = (TT_Round_Func)Round_Up_To_Grid;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* RDTG[]:       Round Down To Grid                                      */
+  /* Opcode range: 0x7D                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static void
+  Ins_RDTG( TT_ExecContext  exc )
+  {
+    exc->GS.round_state = TT_Round_Down_To_Grid;
+    exc->func_round     = (TT_Round_Func)Round_Down_To_Grid;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* ROFF[]:       Round OFF                                               */
+  /* Opcode range: 0x7A                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static void
+  Ins_ROFF( TT_ExecContext  exc )
+  {
+    exc->GS.round_state = TT_Round_Off;
+    exc->func_round     = (TT_Round_Func)Round_None;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SROUND[]:     Super ROUND                                             */
+  /* Opcode range: 0x76                                                    */
+  /* Stack:        Eint8 -->                                               */
+  /*                                                                       */
+  static void
+  Ins_SROUND( TT_ExecContext  exc,
+              FT_Long*        args )
+  {
+    SetSuperRound( exc, 0x4000, args[0] );
+
+    exc->GS.round_state = TT_Round_Super;
+    exc->func_round     = (TT_Round_Func)Round_Super;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* S45ROUND[]:   Super ROUND 45 degrees                                  */
+  /* Opcode range: 0x77                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static void
+  Ins_S45ROUND( TT_ExecContext  exc,
+                FT_Long*        args )
+  {
+    SetSuperRound( exc, 0x2D41, args[0] );
+
+    exc->GS.round_state = TT_Round_Super_45;
+    exc->func_round     = (TT_Round_Func)Round_Super_45;
+  }
+
+
   /*************************************************************************/
   /*                                                                       */
   /* GC[a]:        Get Coordinate projected onto                           */
@@ -5298,7 +4786,8 @@
   /*      along the dual projection vector!                                */
   /*                                                                       */
   static void
-  Ins_GC( INS_ARG )
+  Ins_GC( TT_ExecContext  exc,
+          FT_Long*        args )
   {
     FT_ULong    L;
     FT_F26Dot6  R;
@@ -5306,18 +4795,18 @@
 
     L = (FT_ULong)args[0];
 
-    if ( BOUNDSL( L, CUR.zp2.n_points ) )
+    if ( BOUNDSL( L, exc->zp2.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       R = 0;
     }
     else
     {
-      if ( CUR.opcode & 1 )
-        R = CUR_fast_dualproj( &CUR.zp2.org[L] );
+      if ( exc->opcode & 1 )
+        R = FAST_DUALPROJ( &exc->zp2.org[L] );
       else
-        R = CUR_fast_project( &CUR.zp2.cur[L] );
+        R = FAST_PROJECT( &exc->zp2.cur[L] );
     }
 
     args[0] = R;
@@ -5335,7 +4824,8 @@
   /*   OA := OA + ( value - OA.p )/( f.p ) * f                             */
   /*                                                                       */
   static void
-  Ins_SCFS( INS_ARG )
+  Ins_SCFS( TT_ExecContext  exc,
+            FT_Long*        args )
   {
     FT_Long    K;
     FT_UShort  L;
@@ -5343,21 +4833,21 @@
 
     L = (FT_UShort)args[0];
 
-    if ( BOUNDS( L, CUR.zp2.n_points ) )
+    if ( BOUNDS( L, exc->zp2.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    K = CUR_fast_project( &CUR.zp2.cur[L] );
+    K = FAST_PROJECT( &exc->zp2.cur[L] );
 
-    CUR_Func_move( &CUR.zp2, L, args[1] - K );
+    exc->func_move( exc, &exc->zp2, L, args[1] - K );
 
     /* UNDOCUMENTED!  The MS rasterizer does that with */
     /* twilight points (confirmed by Greg Hitchcock)   */
-    if ( CUR.GS.gep2 == 0 )
-      CUR.zp2.org[L] = CUR.zp2.cur[L];
+    if ( exc->GS.gep2 == 0 )
+      exc->zp2.org[L] = exc->zp2.cur[L];
   }
 
 
@@ -5377,7 +4867,8 @@
   /* XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1!                   */
   /*                                                                       */
   static void
-  Ins_MD( INS_ARG )
+  Ins_MD( TT_ExecContext  exc,
+          FT_Long*        args )
   {
     FT_UShort   K, L;
     FT_F26Dot6  D;
@@ -5386,50 +4877,50 @@
     K = (FT_UShort)args[1];
     L = (FT_UShort)args[0];
 
-    if ( BOUNDS( L, CUR.zp0.n_points ) ||
-         BOUNDS( K, CUR.zp1.n_points ) )
+    if ( BOUNDS( L, exc->zp0.n_points ) ||
+         BOUNDS( K, exc->zp1.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       D = 0;
     }
     else
     {
-      if ( CUR.opcode & 1 )
-        D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K );
+      if ( exc->opcode & 1 )
+        D = PROJECT( exc->zp0.cur + L, exc->zp1.cur + K );
       else
       {
         /* XXX: UNDOCUMENTED: twilight zone special case */
 
-        if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 )
+        if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 )
         {
-          FT_Vector*  vec1 = CUR.zp0.org + L;
-          FT_Vector*  vec2 = CUR.zp1.org + K;
+          FT_Vector*  vec1 = exc->zp0.org + L;
+          FT_Vector*  vec2 = exc->zp1.org + K;
 
 
-          D = CUR_Func_dualproj( vec1, vec2 );
+          D = DUALPROJ( vec1, vec2 );
         }
         else
         {
-          FT_Vector*  vec1 = CUR.zp0.orus + L;
-          FT_Vector*  vec2 = CUR.zp1.orus + K;
+          FT_Vector*  vec1 = exc->zp0.orus + L;
+          FT_Vector*  vec2 = exc->zp1.orus + K;
 
 
-          if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
+          if ( exc->metrics.x_scale == exc->metrics.y_scale )
           {
             /* this should be faster */
-            D = CUR_Func_dualproj( vec1, vec2 );
-            D = FT_MulFix( D, CUR.metrics.x_scale );
+            D = DUALPROJ( vec1, vec2 );
+            D = FT_MulFix( D, exc->metrics.x_scale );
           }
           else
           {
             FT_Vector  vec;
 
 
-            vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale );
-            vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale );
+            vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale );
+            vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale );
 
-            D = CUR_fast_dualproj( &vec );
+            D = FAST_DUALPROJ( &vec );
           }
         }
       }
@@ -5437,8 +4928,9 @@
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
-    if ( SUBPIXEL_HINTING                       &&
-         CUR.ignore_x_mode && FT_ABS( D ) == 64 )
+    if ( SUBPIXEL_HINTING   &&
+         exc->ignore_x_mode &&
+         FT_ABS( D ) == 64  )
       D += 1;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
@@ -5448,61 +4940,63 @@
 
   /*************************************************************************/
   /*                                                                       */
-  /* SDPVTL[a]:    Set Dual PVector to Line                                */
+  /* SDPvTL[a]:    Set Dual PVector to Line                                */
   /* Opcode range: 0x86-0x87                                               */
   /* Stack:        uint32 uint32 -->                                       */
   /*                                                                       */
   static void
-  Ins_SDPVTL( INS_ARG )
+  Ins_SDPVTL( TT_ExecContext  exc,
+              FT_Long*        args )
   {
     FT_Long    A, B, C;
     FT_UShort  p1, p2;            /* was FT_Int in pas type ERROR */
-    FT_Int     aOpc = CUR.opcode;
+
+    FT_Byte  opcode = exc->opcode;
 
 
     p1 = (FT_UShort)args[1];
     p2 = (FT_UShort)args[0];
 
-    if ( BOUNDS( p2, CUR.zp1.n_points ) ||
-         BOUNDS( p1, CUR.zp2.n_points ) )
+    if ( BOUNDS( p2, exc->zp1.n_points ) ||
+         BOUNDS( p1, exc->zp2.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
     {
-      FT_Vector* v1 = CUR.zp1.org + p2;
-      FT_Vector* v2 = CUR.zp2.org + p1;
+      FT_Vector* v1 = exc->zp1.org + p2;
+      FT_Vector* v2 = exc->zp2.org + p1;
 
 
       A = v1->x - v2->x;
       B = v1->y - v2->y;
 
-      /* If v1 == v2, SDPVTL behaves the same as */
+      /* If v1 == v2, SDPvTL behaves the same as */
       /* SVTCA[X], respectively.                 */
       /*                                         */
       /* Confirmed by Greg Hitchcock.            */
 
       if ( A == 0 && B == 0 )
       {
-        A    = 0x4000;
-        aOpc = 0;
+        A      = 0x4000;
+        opcode = 0;
       }
     }
 
-    if ( ( aOpc & 1 ) != 0 )
+    if ( ( opcode & 1 ) != 0 )
     {
       C =  B;   /* counter clockwise rotation */
       B =  A;
       A = -C;
     }
 
-    NORMalize( A, B, &CUR.GS.dualVector );
+    Normalize( A, B, &exc->GS.dualVector );
 
     {
-      FT_Vector*  v1 = CUR.zp1.cur + p2;
-      FT_Vector*  v2 = CUR.zp2.cur + p1;
+      FT_Vector*  v1 = exc->zp1.cur + p2;
+      FT_Vector*  v2 = exc->zp2.cur + p1;
 
 
       A = v1->x - v2->x;
@@ -5510,23 +5004,21 @@
 
       if ( A == 0 && B == 0 )
       {
-        A    = 0x4000;
-        aOpc = 0;
+        A      = 0x4000;
+        opcode = 0;
       }
     }
 
-    if ( ( aOpc & 1 ) != 0 )
+    if ( ( opcode & 1 ) != 0 )
     {
       C =  B;   /* counter clockwise rotation */
       B =  A;
       A = -C;
     }
 
-    NORMalize( A, B, &CUR.GS.projVector );
-
+    Normalize( A, B, &exc->GS.projVector );
     GUESS_VECTOR( freeVector );
-
-    COMPUTE_Funcs();
+    Compute_Funcs( exc );
   }
 
 
@@ -5537,25 +5029,26 @@
   /* Stack:        uint32 -->                                              */
   /*                                                                       */
   static void
-  Ins_SZP0( INS_ARG )
+  Ins_SZP0( TT_ExecContext  exc,
+            FT_Long*        args )
   {
     switch ( (FT_Int)args[0] )
     {
     case 0:
-      CUR.zp0 = CUR.twilight;
+      exc->zp0 = exc->twilight;
       break;
 
     case 1:
-      CUR.zp0 = CUR.pts;
+      exc->zp0 = exc->pts;
       break;
 
     default:
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    CUR.GS.gep0 = (FT_UShort)args[0];
+    exc->GS.gep0 = (FT_UShort)args[0];
   }
 
 
@@ -5566,25 +5059,26 @@
   /* Stack:        uint32 -->                                              */
   /*                                                                       */
   static void
-  Ins_SZP1( INS_ARG )
+  Ins_SZP1( TT_ExecContext  exc,
+            FT_Long*        args )
   {
     switch ( (FT_Int)args[0] )
     {
     case 0:
-      CUR.zp1 = CUR.twilight;
+      exc->zp1 = exc->twilight;
       break;
 
     case 1:
-      CUR.zp1 = CUR.pts;
+      exc->zp1 = exc->pts;
       break;
 
     default:
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    CUR.GS.gep1 = (FT_UShort)args[0];
+    exc->GS.gep1 = (FT_UShort)args[0];
   }
 
 
@@ -5595,25 +5089,26 @@
   /* Stack:        uint32 -->                                              */
   /*                                                                       */
   static void
-  Ins_SZP2( INS_ARG )
+  Ins_SZP2( TT_ExecContext  exc,
+            FT_Long*        args )
   {
     switch ( (FT_Int)args[0] )
     {
     case 0:
-      CUR.zp2 = CUR.twilight;
+      exc->zp2 = exc->twilight;
       break;
 
     case 1:
-      CUR.zp2 = CUR.pts;
+      exc->zp2 = exc->pts;
       break;
 
     default:
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    CUR.GS.gep2 = (FT_UShort)args[0];
+    exc->GS.gep2 = (FT_UShort)args[0];
   }
 
 
@@ -5624,60 +5119,82 @@
   /* Stack:        uint32 -->                                              */
   /*                                                                       */
   static void
-  Ins_SZPS( INS_ARG )
+  Ins_SZPS( TT_ExecContext  exc,
+            FT_Long*        args )
   {
     switch ( (FT_Int)args[0] )
     {
     case 0:
-      CUR.zp0 = CUR.twilight;
+      exc->zp0 = exc->twilight;
       break;
 
     case 1:
-      CUR.zp0 = CUR.pts;
+      exc->zp0 = exc->pts;
       break;
 
     default:
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    CUR.zp1 = CUR.zp0;
-    CUR.zp2 = CUR.zp0;
+    exc->zp1 = exc->zp0;
+    exc->zp2 = exc->zp0;
 
-    CUR.GS.gep0 = (FT_UShort)args[0];
-    CUR.GS.gep1 = (FT_UShort)args[0];
-    CUR.GS.gep2 = (FT_UShort)args[0];
+    exc->GS.gep0 = (FT_UShort)args[0];
+    exc->GS.gep1 = (FT_UShort)args[0];
+    exc->GS.gep2 = (FT_UShort)args[0];
   }
 
 
   /*************************************************************************/
   /*                                                                       */
   /* INSTCTRL[]:   INSTruction ConTRoL                                     */
-  /* Opcode range: 0x8e                                                    */
+  /* Opcode range: 0x8E                                                    */
   /* Stack:        int32 int32 -->                                         */
   /*                                                                       */
   static void
-  Ins_INSTCTRL( INS_ARG )
+  Ins_INSTCTRL( TT_ExecContext  exc,
+                FT_Long*        args )
   {
-    FT_Long  K, L;
+    FT_Long  K, L, Kf;
 
 
     K = args[1];
     L = args[0];
 
-    if ( K < 1 || K > 2 )
+    /* selector values cannot be `OR'ed;                 */
+    /* they are indices starting with index 1, not flags */
+    if ( K < 1 || K > 3 )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    if ( L != 0 )
-        L = K;
+    /* convert index to flag value */
+    Kf = 1 << ( K - 1 );
 
-    CUR.GS.instruct_control = FT_BOOL(
-      ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L );
+    if ( L != 0 )
+    {
+      /* arguments to selectors look like flag values */
+      if ( L != Kf )
+      {
+        if ( exc->pedantic_hinting )
+          exc->error = FT_THROW( Invalid_Reference );
+        return;
+      }
+    }
+
+    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 );
+#endif
   }
 
 
@@ -5688,7 +5205,8 @@
   /* Stack:        uint32? -->                                             */
   /*                                                                       */
   static void
-  Ins_SCANCTRL( INS_ARG )
+  Ins_SCANCTRL( TT_ExecContext  exc,
+                FT_Long*        args )
   {
     FT_Int  A;
 
@@ -5698,32 +5216,32 @@
 
     if ( A == 0xFF )
     {
-      CUR.GS.scan_control = TRUE;
+      exc->GS.scan_control = TRUE;
       return;
     }
     else if ( A == 0 )
     {
-      CUR.GS.scan_control = FALSE;
+      exc->GS.scan_control = FALSE;
       return;
     }
 
-    if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A )
-      CUR.GS.scan_control = TRUE;
+    if ( ( args[0] & 0x100 ) != 0 && exc->tt_metrics.ppem <= A )
+      exc->GS.scan_control = TRUE;
 
-    if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated )
-      CUR.GS.scan_control = TRUE;
+    if ( ( args[0] & 0x200 ) != 0 && exc->tt_metrics.rotated )
+      exc->GS.scan_control = TRUE;
 
-    if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched )
-      CUR.GS.scan_control = TRUE;
+    if ( ( args[0] & 0x400 ) != 0 && exc->tt_metrics.stretched )
+      exc->GS.scan_control = TRUE;
 
-    if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A )
-      CUR.GS.scan_control = FALSE;
+    if ( ( args[0] & 0x800 ) != 0 && exc->tt_metrics.ppem > A )
+      exc->GS.scan_control = FALSE;
 
-    if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated )
-      CUR.GS.scan_control = FALSE;
+    if ( ( args[0] & 0x1000 ) != 0 && exc->tt_metrics.rotated )
+      exc->GS.scan_control = FALSE;
 
-    if ( ( args[0] & 0x2000 ) != 0 && CUR.tt_metrics.stretched )
-      CUR.GS.scan_control = FALSE;
+    if ( ( args[0] & 0x2000 ) != 0 && exc->tt_metrics.stretched )
+      exc->GS.scan_control = FALSE;
   }
 
 
@@ -5734,10 +5252,11 @@
   /* Stack:        uint32? -->                                             */
   /*                                                                       */
   static void
-  Ins_SCANTYPE( INS_ARG )
+  Ins_SCANTYPE( TT_ExecContext  exc,
+                FT_Long*        args )
   {
     if ( args[0] >= 0 )
-      CUR.GS.scan_type = (FT_Int)args[0];
+      exc->GS.scan_type = (FT_Int)args[0];
   }
 
 
@@ -5745,8 +5264,6 @@
   /*                                                                       */
   /* MANAGING OUTLINES                                                     */
   /*                                                                       */
-  /*   Instructions appear in the specification's order.                   */
-  /*                                                                       */
   /*************************************************************************/
 
 
@@ -5757,43 +5274,41 @@
   /* Stack:        uint32... -->                                           */
   /*                                                                       */
   static void
-  Ins_FLIPPT( INS_ARG )
+  Ins_FLIPPT( TT_ExecContext  exc )
   {
     FT_UShort  point;
 
-    FT_UNUSED_ARG;
 
-
-    if ( CUR.top < CUR.GS.loop )
+    if ( exc->top < exc->GS.loop )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Too_Few_Arguments );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Too_Few_Arguments );
       goto Fail;
     }
 
-    while ( CUR.GS.loop > 0 )
+    while ( exc->GS.loop > 0 )
     {
-      CUR.args--;
+      exc->args--;
 
-      point = (FT_UShort)CUR.stack[CUR.args];
+      point = (FT_UShort)exc->stack[exc->args];
 
-      if ( BOUNDS( point, CUR.pts.n_points ) )
+      if ( BOUNDS( point, exc->pts.n_points ) )
       {
-        if ( CUR.pedantic_hinting )
+        if ( exc->pedantic_hinting )
         {
-          CUR.error = FT_THROW( Invalid_Reference );
+          exc->error = FT_THROW( Invalid_Reference );
           return;
         }
       }
       else
-        CUR.pts.tags[point] ^= FT_CURVE_TAG_ON;
+        exc->pts.tags[point] ^= FT_CURVE_TAG_ON;
 
-      CUR.GS.loop--;
+      exc->GS.loop--;
     }
 
   Fail:
-    CUR.GS.loop = 1;
-    CUR.new_top = CUR.args;
+    exc->GS.loop = 1;
+    exc->new_top = exc->args;
   }
 
 
@@ -5804,7 +5319,8 @@
   /* Stack:        uint32 uint32 -->                                       */
   /*                                                                       */
   static void
-  Ins_FLIPRGON( INS_ARG )
+  Ins_FLIPRGON( TT_ExecContext  exc,
+                FT_Long*        args )
   {
     FT_UShort  I, K, L;
 
@@ -5812,16 +5328,16 @@
     K = (FT_UShort)args[1];
     L = (FT_UShort)args[0];
 
-    if ( BOUNDS( K, CUR.pts.n_points ) ||
-         BOUNDS( L, CUR.pts.n_points ) )
+    if ( BOUNDS( K, exc->pts.n_points ) ||
+         BOUNDS( L, exc->pts.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
     for ( I = L; I <= K; I++ )
-      CUR.pts.tags[I] |= FT_CURVE_TAG_ON;
+      exc->pts.tags[I] |= FT_CURVE_TAG_ON;
   }
 
 
@@ -5832,7 +5348,8 @@
   /* Stack:        uint32 uint32 -->                                       */
   /*                                                                       */
   static void
-  Ins_FLIPRGOFF( INS_ARG )
+  Ins_FLIPRGOFF( TT_ExecContext  exc,
+                 FT_Long*        args )
   {
     FT_UShort  I, K, L;
 
@@ -5840,45 +5357,46 @@
     K = (FT_UShort)args[1];
     L = (FT_UShort)args[0];
 
-    if ( BOUNDS( K, CUR.pts.n_points ) ||
-         BOUNDS( L, CUR.pts.n_points ) )
+    if ( BOUNDS( K, exc->pts.n_points ) ||
+         BOUNDS( L, exc->pts.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
     for ( I = L; I <= K; I++ )
-      CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON;
+      exc->pts.tags[I] &= ~FT_CURVE_TAG_ON;
   }
 
 
   static FT_Bool
-  Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6*   x,
-                                       FT_F26Dot6*   y,
-                                       TT_GlyphZone  zone,
-                                       FT_UShort*    refp )
+  Compute_Point_Displacement( TT_ExecContext  exc,
+                              FT_F26Dot6*     x,
+                              FT_F26Dot6*     y,
+                              TT_GlyphZone    zone,
+                              FT_UShort*      refp )
   {
     TT_GlyphZoneRec  zp;
     FT_UShort        p;
     FT_F26Dot6       d;
 
 
-    if ( CUR.opcode & 1 )
+    if ( exc->opcode & 1 )
     {
-      zp = CUR.zp0;
-      p  = CUR.GS.rp1;
+      zp = exc->zp0;
+      p  = exc->GS.rp1;
     }
     else
     {
-      zp = CUR.zp1;
-      p  = CUR.GS.rp2;
+      zp = exc->zp1;
+      p  = exc->GS.rp2;
     }
 
     if ( BOUNDS( p, zp.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       *refp = 0;
       return FAILURE;
     }
@@ -5886,12 +5404,12 @@
     *zone = zp;
     *refp = p;
 
-    d = CUR_Func_project( zp.cur + p, zp.org + p );
+    d = PROJECT( zp.cur + p, zp.org + p );
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    if ( CUR.face->unpatented_hinting )
+    if ( exc->face->unpatented_hinting )
     {
-      if ( CUR.GS.both_x_axis )
+      if ( exc->GS.both_x_axis )
       {
         *x = d;
         *y = 0;
@@ -5905,8 +5423,8 @@
     else
 #endif
     {
-      *x = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.x, CUR.F_dot_P );
-      *y = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.y, CUR.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;
@@ -5914,42 +5432,43 @@
 
 
   static void
-  Move_Zp2_Point( EXEC_OP_ FT_UShort   point,
-                           FT_F26Dot6  dx,
-                           FT_F26Dot6  dy,
-                           FT_Bool     touch )
+  Move_Zp2_Point( TT_ExecContext  exc,
+                  FT_UShort       point,
+                  FT_F26Dot6      dx,
+                  FT_F26Dot6      dy,
+                  FT_Bool         touch )
   {
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    if ( CUR.face->unpatented_hinting )
+    if ( exc->face->unpatented_hinting )
     {
-      if ( CUR.GS.both_x_axis )
+      if ( exc->GS.both_x_axis )
       {
-        CUR.zp2.cur[point].x += dx;
+        exc->zp2.cur[point].x += dx;
         if ( touch )
-          CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
+          exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
       }
       else
       {
-        CUR.zp2.cur[point].y += dy;
+        exc->zp2.cur[point].y += dy;
         if ( touch )
-          CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
+          exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
       }
       return;
     }
 #endif
 
-    if ( CUR.GS.freeVector.x != 0 )
+    if ( exc->GS.freeVector.x != 0 )
     {
-      CUR.zp2.cur[point].x += dx;
+      exc->zp2.cur[point].x += dx;
       if ( touch )
-        CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
+        exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
     }
 
-    if ( CUR.GS.freeVector.y != 0 )
+    if ( exc->GS.freeVector.y != 0 )
     {
-      CUR.zp2.cur[point].y += dy;
+      exc->zp2.cur[point].y += dy;
       if ( touch )
-        CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
+        exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
     }
   }
 
@@ -5961,57 +5480,54 @@
   /* Stack:        uint32... -->                                           */
   /*                                                                       */
   static void
-  Ins_SHP( INS_ARG )
+  Ins_SHP( TT_ExecContext  exc )
   {
     TT_GlyphZoneRec  zp;
     FT_UShort        refp;
 
-    FT_F26Dot6       dx,
-                     dy;
+    FT_F26Dot6       dx, dy;
     FT_UShort        point;
 
-    FT_UNUSED_ARG;
 
-
-    if ( CUR.top < CUR.GS.loop )
+    if ( exc->top < exc->GS.loop )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
-    if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
+    if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
       return;
 
-    while ( CUR.GS.loop > 0 )
+    while ( exc->GS.loop > 0 )
     {
-      CUR.args--;
-      point = (FT_UShort)CUR.stack[CUR.args];
+      exc->args--;
+      point = (FT_UShort)exc->stack[exc->args];
 
-      if ( BOUNDS( point, CUR.zp2.n_points ) )
+      if ( BOUNDS( point, exc->zp2.n_points ) )
       {
-        if ( CUR.pedantic_hinting )
+        if ( exc->pedantic_hinting )
         {
-          CUR.error = FT_THROW( Invalid_Reference );
+          exc->error = FT_THROW( Invalid_Reference );
           return;
         }
       }
       else
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
       /* doesn't follow Cleartype spec but produces better result */
-      if ( SUBPIXEL_HINTING  &&
-           CUR.ignore_x_mode )
-        MOVE_Zp2_Point( point, 0, dy, TRUE );
+      if ( SUBPIXEL_HINTING   &&
+           exc->ignore_x_mode )
+        Move_Zp2_Point( exc, point, 0, dy, TRUE );
       else
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-        MOVE_Zp2_Point( point, dx, dy, TRUE );
+        Move_Zp2_Point( exc, point, dx, dy, TRUE );
 
-      CUR.GS.loop--;
+      exc->GS.loop--;
     }
 
   Fail:
-    CUR.GS.loop = 1;
-    CUR.new_top = CUR.args;
+    exc->GS.loop = 1;
+    exc->new_top = exc->args;
   }
 
 
@@ -6026,7 +5542,8 @@
   /*               zero which includes all points of it.                   */
   /*                                                                       */
   static void
-  Ins_SHC( INS_ARG )
+  Ins_SHC( TT_ExecContext  exc,
+           FT_Long*        args )
   {
     TT_GlyphZoneRec  zp;
     FT_UShort        refp;
@@ -6036,36 +5553,36 @@
     FT_UShort        start, limit, i;
 
 
-    contour = (FT_UShort)args[0];
-    bounds  = ( CUR.GS.gep2 == 0 ) ? 1 : CUR.zp2.n_contours;
+    contour = (FT_Short)args[0];
+    bounds  = ( exc->GS.gep2 == 0 ) ? 1 : exc->zp2.n_contours;
 
     if ( BOUNDS( contour, bounds ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
+    if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
       return;
 
     if ( contour == 0 )
       start = 0;
     else
-      start = (FT_UShort)( CUR.zp2.contours[contour - 1] + 1 -
-                           CUR.zp2.first_point );
+      start = (FT_UShort)( exc->zp2.contours[contour - 1] + 1 -
+                           exc->zp2.first_point );
 
     /* we use the number of points if in the twilight zone */
-    if ( CUR.GS.gep2 == 0 )
-      limit = CUR.zp2.n_points;
+    if ( exc->GS.gep2 == 0 )
+      limit = exc->zp2.n_points;
     else
-      limit = (FT_UShort)( CUR.zp2.contours[contour] -
-                           CUR.zp2.first_point + 1 );
+      limit = (FT_UShort)( exc->zp2.contours[contour] -
+                           exc->zp2.first_point + 1 );
 
     for ( i = start; i < limit; i++ )
     {
-      if ( zp.cur != CUR.zp2.cur || refp != i )
-        MOVE_Zp2_Point( i, dx, dy, TRUE );
+      if ( zp.cur != exc->zp2.cur || refp != i )
+        Move_Zp2_Point( exc, i, dx, dy, TRUE );
     }
   }
 
@@ -6077,7 +5594,8 @@
   /* Stack:        uint32 -->                                              */
   /*                                                                       */
   static void
-  Ins_SHZ( INS_ARG )
+  Ins_SHZ( TT_ExecContext  exc,
+           FT_Long*        args )
   {
     TT_GlyphZoneRec  zp;
     FT_UShort        refp;
@@ -6089,30 +5607,30 @@
 
     if ( BOUNDS( args[0], 2 ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
+    if ( Compute_Point_Displacement( exc, &dx, &dy, &zp, &refp ) )
       return;
 
     /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points.     */
     /*      Twilight zone has no real contours, so use `n_points'. */
     /*      Normal zone's `n_points' includes phantoms, so must    */
     /*      use end of last contour.                               */
-    if ( CUR.GS.gep2 == 0 )
-      limit = (FT_UShort)CUR.zp2.n_points;
-    else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 )
-      limit = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 );
+    if ( exc->GS.gep2 == 0 )
+      limit = (FT_UShort)exc->zp2.n_points;
+    else if ( exc->GS.gep2 == 1 && exc->zp2.n_contours > 0 )
+      limit = (FT_UShort)( exc->zp2.contours[exc->zp2.n_contours - 1] + 1 );
     else
       limit = 0;
 
     /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */
     for ( i = 0; i < limit; i++ )
     {
-      if ( zp.cur != CUR.zp2.cur || refp != i )
-        MOVE_Zp2_Point( i, dx, dy, FALSE );
+      if ( zp.cur != exc->zp2.cur || refp != i )
+        Move_Zp2_Point( exc, i, dx, dy, FALSE );
     }
   }
 
@@ -6124,7 +5642,8 @@
   /* Stack:        f26.6 uint32... -->                                     */
   /*                                                                       */
   static void
-  Ins_SHPIX( INS_ARG )
+  Ins_SHPIX( TT_ExecContext  exc,
+             FT_Long*        args )
   {
     FT_F26Dot6  dx, dy;
     FT_UShort   point;
@@ -6133,17 +5652,17 @@
 #endif
 
 
-    if ( CUR.top < CUR.GS.loop + 1 )
+    if ( exc->top < exc->GS.loop + 1 )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
-    if ( CUR.face->unpatented_hinting )
+    if ( exc->face->unpatented_hinting )
     {
-      if ( CUR.GS.both_x_axis )
+      if ( exc->GS.both_x_axis )
       {
         dx = (FT_UInt32)args[0];
         dy = 0;
@@ -6157,115 +5676,115 @@
     else
 #endif
     {
-      dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x );
-      dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y );
+      dx = TT_MulFix14( args[0], exc->GS.freeVector.x );
+      dy = TT_MulFix14( args[0], exc->GS.freeVector.y );
     }
 
-    while ( CUR.GS.loop > 0 )
+    while ( exc->GS.loop > 0 )
     {
-      CUR.args--;
+      exc->args--;
 
-      point = (FT_UShort)CUR.stack[CUR.args];
+      point = (FT_UShort)exc->stack[exc->args];
 
-      if ( BOUNDS( point, CUR.zp2.n_points ) )
+      if ( BOUNDS( point, exc->zp2.n_points ) )
       {
-        if ( CUR.pedantic_hinting )
+        if ( exc->pedantic_hinting )
         {
-          CUR.error = FT_THROW( Invalid_Reference );
+          exc->error = FT_THROW( Invalid_Reference );
           return;
         }
       }
       else
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
       {
-        /*  If not using ignore_x_mode rendering, allow ZP2 move.          */
-        /*  If inline deltas aren't allowed, skip ZP2 move.                */
-        /*  If using ignore_x_mode rendering, allow ZP2 point move if:     */
-        /*   - freedom vector is y and sph_compatibility_mode is off       */
-        /*   - the glyph is composite and the move is in the Y direction   */
-        /*   - the glyph is specifically set to allow SHPIX moves          */
-        /*   - the move is on a previously Y-touched point                 */
+        /*  If not using ignore_x_mode rendering, allow ZP2 move.        */
+        /*  If inline deltas aren't allowed, skip ZP2 move.              */
+        /*  If using ignore_x_mode rendering, allow ZP2 point move if:   */
+        /*   - freedom vector is y and sph_compatibility_mode is off     */
+        /*   - the glyph is composite and the move is in the Y direction */
+        /*   - the glyph is specifically set to allow SHPIX moves        */
+        /*   - the move is on a previously Y-touched point               */
 
-        if ( SUBPIXEL_HINTING  &&
-             CUR.ignore_x_mode )
+        if ( SUBPIXEL_HINTING   &&
+             exc->ignore_x_mode )
         {
           /* save point for later comparison */
-          if ( CUR.GS.freeVector.y != 0 )
-            B1 = CUR.zp2.cur[point].y;
+          if ( exc->GS.freeVector.y != 0 )
+            B1 = exc->zp2.cur[point].y;
           else
-            B1 = CUR.zp2.cur[point].x;
+            B1 = exc->zp2.cur[point].x;
 
-          if ( !CUR.face->sph_compatibility_mode &&
-               CUR.GS.freeVector.y != 0          )
+          if ( !exc->face->sph_compatibility_mode &&
+               exc->GS.freeVector.y != 0          )
           {
-            MOVE_Zp2_Point( point, dx, dy, TRUE );
+            Move_Zp2_Point( exc, point, dx, dy, TRUE );
 
             /* save new point */
-            if ( CUR.GS.freeVector.y != 0 )
+            if ( exc->GS.freeVector.y != 0 )
             {
-              B2 = CUR.zp2.cur[point].y;
+              B2 = exc->zp2.cur[point].y;
 
               /* reverse any disallowed moves */
-              if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
-                   ( B1 & 63 ) != 0                                          &&
-                   ( B2 & 63 ) != 0                                          &&
-                    B1 != B2                                                 )
-                MOVE_Zp2_Point( point, -dx, -dy, TRUE );
+              if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
+                   ( B1 & 63 ) != 0                                           &&
+                   ( B2 & 63 ) != 0                                           &&
+                   B1 != B2                                                   )
+                Move_Zp2_Point( exc, point, -dx, -dy, TRUE );
             }
           }
-          else if ( CUR.face->sph_compatibility_mode )
+          else if ( exc->face->sph_compatibility_mode )
           {
-            if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
+            if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
             {
               dx = FT_PIX_ROUND( B1 + dx ) - B1;
               dy = FT_PIX_ROUND( B1 + dy ) - B1;
             }
 
             /* skip post-iup deltas */
-            if ( CUR.iup_called                                          &&
-                 ( ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) ||
-                   ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) )
+            if ( exc->iup_called                                          &&
+                 ( ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) ||
+                   ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) )
               goto Skip;
 
-            if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) &&
-                  ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) ||
-                    ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y )   ||
-                    ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX )     )   )
-              MOVE_Zp2_Point( point, 0, dy, TRUE );
+            if ( !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) &&
+                  ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
+                    ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y )    ||
+                    ( exc->sph_tweak_flags & SPH_TWEAK_DO_SHPIX )      )  )
+              Move_Zp2_Point( exc, point, 0, dy, TRUE );
 
             /* save new point */
-            if ( CUR.GS.freeVector.y != 0 )
+            if ( exc->GS.freeVector.y != 0 )
             {
-              B2 = CUR.zp2.cur[point].y;
+              B2 = exc->zp2.cur[point].y;
 
               /* reverse any disallowed moves */
               if ( ( B1 & 63 ) == 0 &&
                    ( B2 & 63 ) != 0 &&
                    B1 != B2         )
-                MOVE_Zp2_Point( point, 0, -dy, TRUE );
+                Move_Zp2_Point( exc, point, 0, -dy, TRUE );
             }
           }
-          else if ( CUR.sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
-            MOVE_Zp2_Point( point, dx, dy, TRUE );
+          else if ( exc->sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
+            Move_Zp2_Point( exc, point, dx, dy, TRUE );
         }
         else
-          MOVE_Zp2_Point( point, dx, dy, TRUE );
+          Move_Zp2_Point( exc, point, dx, dy, TRUE );
       }
 
     Skip:
 
 #else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-        MOVE_Zp2_Point( point, dx, dy, TRUE );
+      Move_Zp2_Point( exc, point, dx, dy, TRUE );
 
 #endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-      CUR.GS.loop--;
+      exc->GS.loop--;
     }
 
   Fail:
-    CUR.GS.loop = 1;
-    CUR.new_top = CUR.args;
+    exc->GS.loop = 1;
+    exc->new_top = exc->args;
   }
 
 
@@ -6276,7 +5795,8 @@
   /* Stack:        f26.6 uint32 -->                                        */
   /*                                                                       */
   static void
-  Ins_MSIRP( INS_ARG )
+  Ins_MSIRP( TT_ExecContext  exc,
+             FT_Long*        args )
   {
     FT_UShort   point;
     FT_F26Dot6  distance;
@@ -6287,11 +5807,11 @@
 
     if ( SUBPIXEL_HINTING )
     {
-      control_value_cutin = CUR.GS.control_value_cutin;
+      control_value_cutin = exc->GS.control_value_cutin;
 
-      if ( CUR.ignore_x_mode                                 &&
-           CUR.GS.freeVector.x != 0                          &&
-           !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+      if ( exc->ignore_x_mode                                 &&
+           exc->GS.freeVector.x != 0                          &&
+           !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
         control_value_cutin = 0;
     }
 
@@ -6299,42 +5819,41 @@
 
     point = (FT_UShort)args[0];
 
-    if ( BOUNDS( point,      CUR.zp1.n_points ) ||
-         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+    if ( BOUNDS( point,       exc->zp1.n_points ) ||
+         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
     /* UNDOCUMENTED!  The MS rasterizer does that with */
     /* twilight points (confirmed by Greg Hitchcock)   */
-    if ( CUR.GS.gep1 == 0 )
+    if ( exc->GS.gep1 == 0 )
     {
-      CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0];
-      CUR_Func_move_orig( &CUR.zp1, point, args[1] );
-      CUR.zp1.cur[point] = CUR.zp1.org[point];
+      exc->zp1.org[point] = exc->zp0.org[exc->GS.rp0];
+      exc->func_move_orig( exc, &exc->zp1, point, args[1] );
+      exc->zp1.cur[point] = exc->zp1.org[point];
     }
 
-    distance = CUR_Func_project( CUR.zp1.cur + point,
-                                 CUR.zp0.cur + CUR.GS.rp0 );
+    distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     /* subpixel hinting - make MSIRP respect CVT cut-in; */
     if ( SUBPIXEL_HINTING                                    &&
-         CUR.ignore_x_mode                                   &&
-         CUR.GS.freeVector.x != 0                            &&
+         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 */
 
-    CUR_Func_move( &CUR.zp1, point, args[1] - distance );
+    exc->func_move( exc, &exc->zp1, point, args[1] - distance );
 
-    CUR.GS.rp1 = CUR.GS.rp0;
-    CUR.GS.rp2 = point;
+    exc->GS.rp1 = exc->GS.rp0;
+    exc->GS.rp2 = point;
 
-    if ( ( CUR.opcode & 1 ) != 0 )
-      CUR.GS.rp0 = point;
+    if ( ( exc->opcode & 1 ) != 0 )
+      exc->GS.rp0 = point;
   }
 
 
@@ -6345,7 +5864,8 @@
   /* Stack:        uint32 -->                                              */
   /*                                                                       */
   static void
-  Ins_MDAP( INS_ARG )
+  Ins_MDAP( TT_ExecContext  exc,
+            FT_Long*        args )
   {
     FT_UShort   point;
     FT_F26Dot6  cur_dist;
@@ -6354,36 +5874,38 @@
 
     point = (FT_UShort)args[0];
 
-    if ( BOUNDS( point, CUR.zp0.n_points ) )
+    if ( BOUNDS( point, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    if ( ( CUR.opcode & 1 ) != 0 )
+    if ( ( exc->opcode & 1 ) != 0 )
     {
-      cur_dist = CUR_fast_project( &CUR.zp0.cur[point] );
+      cur_dist = FAST_PROJECT( &exc->zp0.cur[point] );
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( SUBPIXEL_HINTING         &&
-           CUR.ignore_x_mode        &&
-           CUR.GS.freeVector.x != 0 )
-        distance = ROUND_None(
+      if ( SUBPIXEL_HINTING          &&
+           exc->ignore_x_mode        &&
+           exc->GS.freeVector.x != 0 )
+        distance = Round_None(
+                     exc,
                      cur_dist,
-                     CUR.tt_metrics.compensations[0] ) - cur_dist;
+                     exc->tt_metrics.compensations[0] ) - cur_dist;
       else
 #endif
-        distance = CUR_Func_round(
+        distance = exc->func_round(
+                     exc,
                      cur_dist,
-                     CUR.tt_metrics.compensations[0] ) - cur_dist;
+                     exc->tt_metrics.compensations[0] ) - cur_dist;
     }
     else
       distance = 0;
 
-    CUR_Func_move( &CUR.zp0, point, distance );
+    exc->func_move( exc, &exc->zp0, point, distance );
 
-    CUR.GS.rp0 = point;
-    CUR.GS.rp1 = point;
+    exc->GS.rp0 = point;
+    exc->GS.rp1 = point;
   }
 
 
@@ -6394,7 +5916,8 @@
   /* Stack:        uint32 uint32 -->                                       */
   /*                                                                       */
   static void
-  Ins_MIAP( INS_ARG )
+  Ins_MIAP( TT_ExecContext  exc,
+            FT_Long*        args )
   {
     FT_ULong    cvtEntry;
     FT_UShort   point;
@@ -6403,24 +5926,24 @@
     FT_F26Dot6  control_value_cutin;
 
 
-    control_value_cutin = CUR.GS.control_value_cutin;
+    control_value_cutin = exc->GS.control_value_cutin;
     cvtEntry            = (FT_ULong)args[1];
     point               = (FT_UShort)args[0];
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                  &&
-         CUR.ignore_x_mode                                 &&
-         CUR.GS.freeVector.x != 0                          &&
-         CUR.GS.freeVector.y == 0                          &&
-         !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+    if ( SUBPIXEL_HINTING                                   &&
+         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 */
 
-    if ( BOUNDS( point,     CUR.zp0.n_points ) ||
-         BOUNDSL( cvtEntry, CUR.cvtSize )      )
+    if ( BOUNDS( point,     exc->zp0.n_points ) ||
+         BOUNDSL( cvtEntry, exc->cvtSize )      )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
@@ -6444,56 +5967,58 @@
     /*                                                                    */
     /* Confirmed by Greg Hitchcock.                                       */
 
-    distance = CUR_Func_read_cvt( cvtEntry );
+    distance = exc->func_read_cvt( exc, cvtEntry );
 
-    if ( CUR.GS.gep0 == 0 )   /* If in twilight zone */
+    if ( exc->GS.gep0 == 0 )   /* If in twilight zone */
     {
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
       /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */
       /* Determined via experimentation and may be incorrect...         */
-      if ( !SUBPIXEL_HINTING                     ||
-           ( !CUR.ignore_x_mode                ||
-             !CUR.face->sph_compatibility_mode ) )
+      if ( !SUBPIXEL_HINTING                      ||
+           ( !exc->ignore_x_mode                ||
+             !exc->face->sph_compatibility_mode ) )
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
-        CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance,
-                                            CUR.GS.freeVector.x );
-      CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance,
-                                          CUR.GS.freeVector.y ),
-      CUR.zp0.cur[point]   = CUR.zp0.org[point];
+        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                              &&
-         CUR.ignore_x_mode                             &&
-         ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
-         distance > 0                                  &&
-         CUR.GS.freeVector.y != 0                      )
+    if ( SUBPIXEL_HINTING                               &&
+         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 */
 
-    org_dist = CUR_fast_project( &CUR.zp0.cur[point] );
+    org_dist = FAST_PROJECT( &exc->zp0.cur[point] );
 
-    if ( ( CUR.opcode & 1 ) != 0 )   /* rounding and control cut-in flag */
+    if ( ( exc->opcode & 1 ) != 0 )   /* rounding and control cut-in flag */
     {
       if ( FT_ABS( distance - org_dist ) > control_value_cutin )
         distance = org_dist;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( SUBPIXEL_HINTING         &&
-           CUR.ignore_x_mode        &&
-           CUR.GS.freeVector.x != 0 )
-        distance = ROUND_None( distance,
-                               CUR.tt_metrics.compensations[0] );
+      if ( SUBPIXEL_HINTING          &&
+           exc->ignore_x_mode        &&
+           exc->GS.freeVector.x != 0 )
+        distance = Round_None( exc,
+                               distance,
+                               exc->tt_metrics.compensations[0] );
       else
 #endif
-        distance = CUR_Func_round( distance,
-                                   CUR.tt_metrics.compensations[0] );
+        distance = exc->func_round( exc,
+                                    distance,
+                                    exc->tt_metrics.compensations[0] );
     }
 
-    CUR_Func_move( &CUR.zp0, point, distance - org_dist );
+    exc->func_move( exc, &exc->zp0, point, distance - org_dist );
 
   Fail:
-    CUR.GS.rp0 = point;
-    CUR.GS.rp1 = point;
+    exc->GS.rp0 = point;
+    exc->GS.rp1 = point;
   }
 
 
@@ -6504,29 +6029,30 @@
   /* Stack:        uint32 -->                                              */
   /*                                                                       */
   static void
-  Ins_MDRP( INS_ARG )
+  Ins_MDRP( TT_ExecContext  exc,
+            FT_Long*        args )
   {
     FT_UShort   point;
     FT_F26Dot6  org_dist, distance, minimum_distance;
 
 
-    minimum_distance = CUR.GS.minimum_distance;
+    minimum_distance = exc->GS.minimum_distance;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                  &&
-         CUR.ignore_x_mode                                 &&
-         CUR.GS.freeVector.x != 0                          &&
-         !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+    if ( SUBPIXEL_HINTING                                   &&
+         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 */
 
     point = (FT_UShort)args[0];
 
-    if ( BOUNDS( point,      CUR.zp1.n_points ) ||
-         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+    if ( BOUNDS( point,       exc->zp1.n_points ) ||
+         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
@@ -6535,74 +6061,77 @@
 
     /* XXX: UNDOCUMENTED: twilight zone special case */
 
-    if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 )
+    if ( exc->GS.gep0 == 0 || exc->GS.gep1 == 0 )
     {
-      FT_Vector*  vec1 = &CUR.zp1.org[point];
-      FT_Vector*  vec2 = &CUR.zp0.org[CUR.GS.rp0];
+      FT_Vector*  vec1 = &exc->zp1.org[point];
+      FT_Vector*  vec2 = &exc->zp0.org[exc->GS.rp0];
 
 
-      org_dist = CUR_Func_dualproj( vec1, vec2 );
+      org_dist = DUALPROJ( vec1, vec2 );
     }
     else
     {
-      FT_Vector*  vec1 = &CUR.zp1.orus[point];
-      FT_Vector*  vec2 = &CUR.zp0.orus[CUR.GS.rp0];
+      FT_Vector*  vec1 = &exc->zp1.orus[point];
+      FT_Vector*  vec2 = &exc->zp0.orus[exc->GS.rp0];
 
 
-      if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
+      if ( exc->metrics.x_scale == exc->metrics.y_scale )
       {
         /* this should be faster */
-        org_dist = CUR_Func_dualproj( vec1, vec2 );
-        org_dist = FT_MulFix( org_dist, CUR.metrics.x_scale );
+        org_dist = DUALPROJ( vec1, vec2 );
+        org_dist = FT_MulFix( org_dist, exc->metrics.x_scale );
       }
       else
       {
         FT_Vector  vec;
 
 
-        vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale );
-        vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale );
+        vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale );
+        vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale );
 
-        org_dist = CUR_fast_dualproj( &vec );
+        org_dist = FAST_DUALPROJ( &vec );
       }
     }
 
     /* single width cut-in test */
 
-    if ( FT_ABS( org_dist - CUR.GS.single_width_value ) <
-         CUR.GS.single_width_cutin )
+    if ( FT_ABS( org_dist - exc->GS.single_width_value ) <
+         exc->GS.single_width_cutin )
     {
       if ( org_dist >= 0 )
-        org_dist = CUR.GS.single_width_value;
+        org_dist = exc->GS.single_width_value;
       else
-        org_dist = -CUR.GS.single_width_value;
+        org_dist = -exc->GS.single_width_value;
     }
 
     /* round flag */
 
-    if ( ( CUR.opcode & 4 ) != 0 )
+    if ( ( exc->opcode & 4 ) != 0 )
     {
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-      if ( SUBPIXEL_HINTING         &&
-           CUR.ignore_x_mode        &&
-           CUR.GS.freeVector.x != 0 )
-        distance = ROUND_None(
+      if ( SUBPIXEL_HINTING          &&
+           exc->ignore_x_mode        &&
+           exc->GS.freeVector.x != 0 )
+        distance = Round_None(
+                     exc,
                      org_dist,
-                     CUR.tt_metrics.compensations[CUR.opcode & 3] );
+                     exc->tt_metrics.compensations[exc->opcode & 3] );
       else
 #endif
-      distance = CUR_Func_round(
-                   org_dist,
-                   CUR.tt_metrics.compensations[CUR.opcode & 3] );
+        distance = exc->func_round(
+                     exc,
+                     org_dist,
+                     exc->tt_metrics.compensations[exc->opcode & 3] );
     }
     else
-      distance = ROUND_None(
+      distance = Round_None(
+                   exc,
                    org_dist,
-                   CUR.tt_metrics.compensations[CUR.opcode & 3] );
+                   exc->tt_metrics.compensations[exc->opcode & 3] );
 
     /* minimum distance flag */
 
-    if ( ( CUR.opcode & 8 ) != 0 )
+    if ( ( exc->opcode & 8 ) != 0 )
     {
       if ( org_dist >= 0 )
       {
@@ -6618,17 +6147,16 @@
 
     /* now move the point */
 
-    org_dist = CUR_Func_project( CUR.zp1.cur + point,
-                                 CUR.zp0.cur + CUR.GS.rp0 );
+    org_dist = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
 
-    CUR_Func_move( &CUR.zp1, point, distance - org_dist );
+    exc->func_move( exc, &exc->zp1, point, distance - org_dist );
 
   Fail:
-    CUR.GS.rp1 = CUR.GS.rp0;
-    CUR.GS.rp2 = point;
+    exc->GS.rp1 = exc->GS.rp0;
+    exc->GS.rp2 = point;
 
-    if ( ( CUR.opcode & 16 ) != 0 )
-      CUR.GS.rp0 = point;
+    if ( ( exc->opcode & 16 ) != 0 )
+      exc->GS.rp0 = point;
   }
 
 
@@ -6639,7 +6167,8 @@
   /* Stack:        int32? uint32 -->                                       */
   /*                                                                       */
   static void
-  Ins_MIRP( INS_ARG )
+  Ins_MIRP( TT_ExecContext  exc,
+            FT_Long*        args )
   {
     FT_UShort   point;
     FT_ULong    cvtEntry;
@@ -6657,77 +6186,75 @@
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
 
-    minimum_distance    = CUR.GS.minimum_distance;
-    control_value_cutin = CUR.GS.control_value_cutin;
+    minimum_distance    = exc->GS.minimum_distance;
+    control_value_cutin = exc->GS.control_value_cutin;
     point               = (FT_UShort)args[0];
     cvtEntry            = (FT_ULong)( args[1] + 1 );
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                  &&
-         CUR.ignore_x_mode                                 &&
-         CUR.GS.freeVector.x != 0                          &&
-         !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
+    if ( SUBPIXEL_HINTING                                   &&
+         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 */
 
     /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
 
-    if ( BOUNDS( point,      CUR.zp1.n_points ) ||
-         BOUNDSL( cvtEntry,  CUR.cvtSize + 1 )  ||
-         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+    if ( BOUNDS( point,       exc->zp1.n_points ) ||
+         BOUNDSL( cvtEntry,   exc->cvtSize + 1 )  ||
+         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
     if ( !cvtEntry )
       cvt_dist = 0;
     else
-      cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 );
+      cvt_dist = exc->func_read_cvt( exc, cvtEntry - 1 );
 
     /* single width test */
 
-    if ( FT_ABS( cvt_dist - CUR.GS.single_width_value ) <
-         CUR.GS.single_width_cutin )
+    if ( FT_ABS( cvt_dist - exc->GS.single_width_value ) <
+         exc->GS.single_width_cutin )
     {
       if ( cvt_dist >= 0 )
-        cvt_dist =  CUR.GS.single_width_value;
+        cvt_dist =  exc->GS.single_width_value;
       else
-        cvt_dist = -CUR.GS.single_width_value;
+        cvt_dist = -exc->GS.single_width_value;
     }
 
     /* UNDOCUMENTED!  The MS rasterizer does that with */
     /* twilight points (confirmed by Greg Hitchcock)   */
-    if ( CUR.GS.gep1 == 0 )
+    if ( exc->GS.gep1 == 0 )
     {
-      CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x +
-                             TT_MulFix14( (FT_UInt32)cvt_dist,
-                                          CUR.GS.freeVector.x );
-      CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y +
-                             TT_MulFix14( (FT_UInt32)cvt_dist,
-                                          CUR.GS.freeVector.y );
-      CUR.zp1.cur[point]   = CUR.zp1.org[point];
+      exc->zp1.org[point].x = exc->zp0.org[exc->GS.rp0].x +
+                              TT_MulFix14( cvt_dist,
+                                           exc->GS.freeVector.x );
+      exc->zp1.org[point].y = exc->zp0.org[exc->GS.rp0].y +
+                              TT_MulFix14( cvt_dist,
+                                           exc->GS.freeVector.y );
+      exc->zp1.cur[point]   = exc->zp1.org[point];
     }
 
-    org_dist = CUR_Func_dualproj( &CUR.zp1.org[point],
-                                  &CUR.zp0.org[CUR.GS.rp0] );
-    cur_dist = CUR_Func_project ( &CUR.zp1.cur[point],
-                                  &CUR.zp0.cur[CUR.GS.rp0] );
+    org_dist = DUALPROJ( &exc->zp1.org[point], &exc->zp0.org[exc->GS.rp0] );
+    cur_dist = PROJECT ( &exc->zp1.cur[point], &exc->zp0.cur[exc->GS.rp0] );
 
     /* auto-flip test */
 
-    if ( CUR.GS.auto_flip )
+    if ( exc->GS.auto_flip )
     {
       if ( ( org_dist ^ cvt_dist ) < 0 )
         cvt_dist = -cvt_dist;
     }
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                         &&
-         CUR.ignore_x_mode                                        &&
-         CUR.GS.freeVector.y != 0                                 &&
-         ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
+    if ( SUBPIXEL_HINTING                                          &&
+         exc->ignore_x_mode                                        &&
+         exc->GS.freeVector.y != 0                                 &&
+         ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
     {
       if ( cur_dist < -64 )
         cvt_dist -= 16;
@@ -6738,12 +6265,12 @@
 
     /* control value cut-in and round */
 
-    if ( ( CUR.opcode & 4 ) != 0 )
+    if ( ( exc->opcode & 4 ) != 0 )
     {
       /* XXX: UNDOCUMENTED!  Only perform cut-in test when both points */
       /*      refer to the same zone.                                  */
 
-      if ( CUR.GS.gep0 == CUR.GS.gep1 )
+      if ( exc->GS.gep0 == exc->GS.gep1 )
       {
         /* XXX: According to Greg Hitchcock, the following wording is */
         /*      the right one:                                        */
@@ -6761,32 +6288,34 @@
           cvt_dist = org_dist;
       }
 
-      distance = CUR_Func_round(
+      distance = exc->func_round(
+                   exc,
                    cvt_dist,
-                   CUR.tt_metrics.compensations[CUR.opcode & 3] );
+                   exc->tt_metrics.compensations[exc->opcode & 3] );
     }
     else
     {
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
       /* do cvt cut-in always in MIRP for sph */
-      if ( SUBPIXEL_HINTING           &&
-           CUR.ignore_x_mode          &&
-           CUR.GS.gep0 == CUR.GS.gep1 )
+      if ( SUBPIXEL_HINTING             &&
+           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 */
 
-      distance = ROUND_None(
+      distance = Round_None(
+                   exc,
                    cvt_dist,
-                   CUR.tt_metrics.compensations[CUR.opcode & 3] );
+                   exc->tt_metrics.compensations[exc->opcode & 3] );
     }
 
     /* minimum distance test */
 
-    if ( ( CUR.opcode & 8 ) != 0 )
+    if ( ( exc->opcode & 8 ) != 0 )
     {
       if ( org_dist >= 0 )
       {
@@ -6803,59 +6332,59 @@
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     if ( SUBPIXEL_HINTING )
     {
-      B1 = CUR.zp1.cur[point].y;
+      B1 = exc->zp1.cur[point].y;
 
       /* Round moves if necessary */
-      if ( CUR.ignore_x_mode                                          &&
-           CUR.GS.freeVector.y != 0                                   &&
-           ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
+      if ( exc->ignore_x_mode                                          &&
+           exc->GS.freeVector.y != 0                                   &&
+           ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
         distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist;
 
-      if ( CUR.ignore_x_mode                                      &&
-           CUR.GS.freeVector.y != 0                               &&
-           ( CUR.opcode & 16 ) == 0                               &&
-           ( CUR.opcode & 8 ) == 0                                &&
-           ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
+      if ( exc->ignore_x_mode                                      &&
+           exc->GS.freeVector.y != 0                               &&
+           ( exc->opcode & 16 ) == 0                               &&
+           ( exc->opcode & 8 ) == 0                                &&
+           ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
         distance += 64;
     }
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-    CUR_Func_move( &CUR.zp1, point, distance - cur_dist );
+    exc->func_move( exc, &exc->zp1, point, distance - cur_dist );
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     if ( SUBPIXEL_HINTING )
     {
-      B2 = CUR.zp1.cur[point].y;
+      B2 = exc->zp1.cur[point].y;
 
       /* Reverse move if necessary */
-      if ( CUR.ignore_x_mode )
+      if ( exc->ignore_x_mode )
       {
-        if ( CUR.face->sph_compatibility_mode                          &&
-             CUR.GS.freeVector.y != 0                                  &&
-             ( B1 & 63 ) == 0                                          &&
-             ( B2 & 63 ) != 0                                          )
+        if ( exc->face->sph_compatibility_mode &&
+             exc->GS.freeVector.y != 0         &&
+             ( B1 & 63 ) == 0                  &&
+             ( B2 & 63 ) != 0                  )
           reverse_move = TRUE;
 
-        if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
-             CUR.GS.freeVector.y != 0                                  &&
-             ( B2 & 63 ) != 0                                          &&
-             ( B1 & 63 ) != 0                                          )
+        if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
+             exc->GS.freeVector.y != 0                                  &&
+             ( B2 & 63 ) != 0                                           &&
+             ( B1 & 63 ) != 0                                           )
           reverse_move = TRUE;
       }
 
       if ( reverse_move )
-        CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) );
+        exc->func_move( exc, &exc->zp1, point, -( distance - cur_dist ) );
     }
 
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
   Fail:
-    CUR.GS.rp1 = CUR.GS.rp0;
+    exc->GS.rp1 = exc->GS.rp0;
 
-    if ( ( CUR.opcode & 16 ) != 0 )
-      CUR.GS.rp0 = point;
+    if ( ( exc->opcode & 16 ) != 0 )
+      exc->GS.rp0 = point;
 
-    CUR.GS.rp2 = point;
+    exc->GS.rp2 = point;
   }
 
 
@@ -6866,61 +6395,59 @@
   /* Stack:        uint32 uint32... -->                                    */
   /*                                                                       */
   static void
-  Ins_ALIGNRP( INS_ARG )
+  Ins_ALIGNRP( TT_ExecContext  exc )
   {
     FT_UShort   point;
     FT_F26Dot6  distance;
 
-    FT_UNUSED_ARG;
-
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING                                         &&
-         CUR.ignore_x_mode                                        &&
-         CUR.iup_called                                           &&
-         ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
+    if ( SUBPIXEL_HINTING                                          &&
+         exc->ignore_x_mode                                        &&
+         exc->iup_called                                           &&
+         ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
     {
-      CUR.error = FT_THROW( Invalid_Reference );
+      exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-    if ( CUR.top < CUR.GS.loop ||
-         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+    if ( exc->top < exc->GS.loop                  ||
+         BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
-    while ( CUR.GS.loop > 0 )
+    while ( exc->GS.loop > 0 )
     {
-      CUR.args--;
+      exc->args--;
 
-      point = (FT_UShort)CUR.stack[CUR.args];
+      point = (FT_UShort)exc->stack[exc->args];
 
-      if ( BOUNDS( point, CUR.zp1.n_points ) )
+      if ( BOUNDS( point, exc->zp1.n_points ) )
       {
-        if ( CUR.pedantic_hinting )
+        if ( exc->pedantic_hinting )
         {
-          CUR.error = FT_THROW( Invalid_Reference );
+          exc->error = FT_THROW( Invalid_Reference );
           return;
         }
       }
       else
       {
-        distance = CUR_Func_project( CUR.zp1.cur + point,
-                                     CUR.zp0.cur + CUR.GS.rp0 );
+        distance = PROJECT( exc->zp1.cur + point,
+                            exc->zp0.cur + exc->GS.rp0 );
 
-        CUR_Func_move( &CUR.zp1, point, -distance );
+        exc->func_move( exc, &exc->zp1, point, -distance );
       }
 
-      CUR.GS.loop--;
+      exc->GS.loop--;
     }
 
   Fail:
-    CUR.GS.loop = 1;
-    CUR.new_top = CUR.args;
+    exc->GS.loop = 1;
+    exc->new_top = exc->args;
   }
 
 
@@ -6931,7 +6458,8 @@
   /* Stack:        5 * uint32 -->                                          */
   /*                                                                       */
   static void
-  Ins_ISECT( INS_ARG )
+  Ins_ISECT( TT_ExecContext  exc,
+             FT_Long*        args )
   {
     FT_UShort   point,
                 a0, a1,
@@ -6955,29 +6483,29 @@
     b0 = (FT_UShort)args[3];
     b1 = (FT_UShort)args[4];
 
-    if ( BOUNDS( b0, CUR.zp0.n_points )  ||
-         BOUNDS( b1, CUR.zp0.n_points )  ||
-         BOUNDS( a0, CUR.zp1.n_points )  ||
-         BOUNDS( a1, CUR.zp1.n_points )  ||
-         BOUNDS( point, CUR.zp2.n_points ) )
+    if ( BOUNDS( b0,    exc->zp0.n_points ) ||
+         BOUNDS( b1,    exc->zp0.n_points ) ||
+         BOUNDS( a0,    exc->zp1.n_points ) ||
+         BOUNDS( a1,    exc->zp1.n_points ) ||
+         BOUNDS( point, exc->zp2.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
     /* Cramer's rule */
 
-    dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x;
-    dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y;
+    dbx = exc->zp0.cur[b1].x - exc->zp0.cur[b0].x;
+    dby = exc->zp0.cur[b1].y - exc->zp0.cur[b0].y;
 
-    dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x;
-    day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y;
+    dax = exc->zp1.cur[a1].x - exc->zp1.cur[a0].x;
+    day = exc->zp1.cur[a1].y - exc->zp1.cur[a0].y;
 
-    dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x;
-    dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y;
+    dx = exc->zp0.cur[b0].x - exc->zp1.cur[a0].x;
+    dy = exc->zp0.cur[b0].y - exc->zp1.cur[a0].y;
 
-    CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;
+    exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH;
 
     discriminant = FT_MulDiv( dax, -dby, 0x40 ) +
                    FT_MulDiv( day, dbx, 0x40 );
@@ -6999,21 +6527,21 @@
       R.x = FT_MulDiv( val, dax, discriminant );
       R.y = FT_MulDiv( val, day, discriminant );
 
-      CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x;
-      CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y;
+      exc->zp2.cur[point].x = exc->zp1.cur[a0].x + R.x;
+      exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y;
     }
     else
     {
       /* else, take the middle of the middles of A and B */
 
-      CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x +
-                               CUR.zp1.cur[a1].x +
-                               CUR.zp0.cur[b0].x +
-                               CUR.zp0.cur[b1].x ) / 4;
-      CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y +
-                               CUR.zp1.cur[a1].y +
-                               CUR.zp0.cur[b0].y +
-                               CUR.zp0.cur[b1].y ) / 4;
+      exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x +
+                                exc->zp1.cur[a1].x +
+                                exc->zp0.cur[b0].x +
+                                exc->zp0.cur[b1].x ) / 4;
+      exc->zp2.cur[point].y = ( exc->zp1.cur[a0].y +
+                                exc->zp1.cur[a1].y +
+                                exc->zp0.cur[b0].y +
+                                exc->zp0.cur[b1].y ) / 4;
     }
   }
 
@@ -7025,7 +6553,8 @@
   /* Stack:        uint32 uint32 -->                                       */
   /*                                                                       */
   static void
-  Ins_ALIGNPTS( INS_ARG )
+  Ins_ALIGNPTS( TT_ExecContext  exc,
+                FT_Long*        args )
   {
     FT_UShort   p1, p2;
     FT_F26Dot6  distance;
@@ -7034,19 +6563,18 @@
     p1 = (FT_UShort)args[0];
     p2 = (FT_UShort)args[1];
 
-    if ( BOUNDS( p1, CUR.zp1.n_points ) ||
-         BOUNDS( p2, CUR.zp0.n_points ) )
+    if ( BOUNDS( p1, exc->zp1.n_points ) ||
+         BOUNDS( p2, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
-    distance = CUR_Func_project( CUR.zp0.cur + p2,
-                                 CUR.zp1.cur + p1 ) / 2;
+    distance = PROJECT( exc->zp0.cur + p2, exc->zp1.cur + p1 ) / 2;
 
-    CUR_Func_move( &CUR.zp1, p1, distance );
-    CUR_Func_move( &CUR.zp0, p2, -distance );
+    exc->func_move( exc, &exc->zp1, p1, distance );
+    exc->func_move( exc, &exc->zp0, p2, -distance );
   }
 
 
@@ -7060,50 +6588,48 @@
   /* SOMETIMES, DUMBER CODE IS BETTER CODE */
 
   static void
-  Ins_IP( INS_ARG )
+  Ins_IP( TT_ExecContext  exc )
   {
     FT_F26Dot6  old_range, cur_range;
     FT_Vector*  orus_base;
     FT_Vector*  cur_base;
     FT_Int      twilight;
 
-    FT_UNUSED_ARG;
 
-
-    if ( CUR.top < CUR.GS.loop )
+    if ( exc->top < exc->GS.loop )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
     /*
      * We need to deal in a special way with the twilight zone.
-     * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0),
+     * Otherwise, by definition, the value of exc->twilight.orus[n] is (0,0),
      * for every n.
      */
-    twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0;
+    twilight = exc->GS.gep0 == 0 || exc->GS.gep1 == 0 || exc->GS.gep2 == 0;
 
-    if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) )
+    if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
     }
 
     if ( twilight )
-      orus_base = &CUR.zp0.org[CUR.GS.rp1];
+      orus_base = &exc->zp0.org[exc->GS.rp1];
     else
-      orus_base = &CUR.zp0.orus[CUR.GS.rp1];
+      orus_base = &exc->zp0.orus[exc->GS.rp1];
 
-    cur_base = &CUR.zp0.cur[CUR.GS.rp1];
+    cur_base = &exc->zp0.cur[exc->GS.rp1];
 
     /* XXX: There are some glyphs in some braindead but popular */
     /*      fonts out there (e.g. [aeu]grave in monotype.ttf)   */
     /*      calling IP[] with bad values of rp[12].             */
     /*      Do something sane when this odd thing happens.      */
-    if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ||
-         BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) )
+    if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) ||
+         BOUNDS( exc->GS.rp2, exc->zp1.n_points ) )
     {
       old_range = 0;
       cur_range = 0;
@@ -7111,62 +6637,60 @@
     else
     {
       if ( twilight )
-        old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2],
-                                       orus_base );
-      else if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
-        old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2],
-                                       orus_base );
+        old_range = DUALPROJ( &exc->zp1.org[exc->GS.rp2], orus_base );
+      else if ( exc->metrics.x_scale == exc->metrics.y_scale )
+        old_range = DUALPROJ( &exc->zp1.orus[exc->GS.rp2], orus_base );
       else
       {
         FT_Vector  vec;
 
 
-        vec.x = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x,
-                           CUR.metrics.x_scale );
-        vec.y = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y,
-                           CUR.metrics.y_scale );
+        vec.x = FT_MulFix( exc->zp1.orus[exc->GS.rp2].x - orus_base->x,
+                           exc->metrics.x_scale );
+        vec.y = FT_MulFix( exc->zp1.orus[exc->GS.rp2].y - orus_base->y,
+                           exc->metrics.y_scale );
 
-        old_range = CUR_fast_dualproj( &vec );
+        old_range = FAST_DUALPROJ( &vec );
       }
 
-      cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base );
+      cur_range = PROJECT( &exc->zp1.cur[exc->GS.rp2], cur_base );
     }
 
-    for ( ; CUR.GS.loop > 0; --CUR.GS.loop )
+    for ( ; exc->GS.loop > 0; --exc->GS.loop )
     {
-      FT_UInt     point = (FT_UInt)CUR.stack[--CUR.args];
+      FT_UInt     point = (FT_UInt)exc->stack[--exc->args];
       FT_F26Dot6  org_dist, cur_dist, new_dist;
 
 
       /* check point bounds */
-      if ( BOUNDS( point, CUR.zp2.n_points ) )
+      if ( BOUNDS( point, exc->zp2.n_points ) )
       {
-        if ( CUR.pedantic_hinting )
+        if ( exc->pedantic_hinting )
         {
-          CUR.error = FT_THROW( Invalid_Reference );
+          exc->error = FT_THROW( Invalid_Reference );
           return;
         }
         continue;
       }
 
       if ( twilight )
-        org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base );
-      else if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
-        org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base );
+        org_dist = DUALPROJ( &exc->zp2.org[point], orus_base );
+      else if ( exc->metrics.x_scale == exc->metrics.y_scale )
+        org_dist = DUALPROJ( &exc->zp2.orus[point], orus_base );
       else
       {
         FT_Vector  vec;
 
 
-        vec.x = FT_MulFix( CUR.zp2.orus[point].x - orus_base->x,
-                           CUR.metrics.x_scale );
-        vec.y = FT_MulFix( CUR.zp2.orus[point].y - orus_base->y,
-                           CUR.metrics.y_scale );
+        vec.x = FT_MulFix( exc->zp2.orus[point].x - orus_base->x,
+                           exc->metrics.x_scale );
+        vec.y = FT_MulFix( exc->zp2.orus[point].y - orus_base->y,
+                           exc->metrics.y_scale );
 
-        org_dist = CUR_fast_dualproj( &vec );
+        org_dist = FAST_DUALPROJ( &vec );
       }
 
-      cur_dist = CUR_Func_project( &CUR.zp2.cur[point], cur_base );
+      cur_dist = PROJECT( &exc->zp2.cur[point], cur_base );
 
       if ( org_dist )
       {
@@ -7196,12 +6720,15 @@
       else
         new_dist = 0;
 
-      CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist );
+      exc->func_move( exc,
+                      &exc->zp2,
+                      (FT_UShort)point,
+                      new_dist - cur_dist );
     }
 
   Fail:
-    CUR.GS.loop = 1;
-    CUR.new_top = CUR.args;
+    exc->GS.loop = 1;
+    exc->new_top = exc->args;
   }
 
 
@@ -7212,7 +6739,8 @@
   /* Stack:        uint32 -->                                              */
   /*                                                                       */
   static void
-  Ins_UTP( INS_ARG )
+  Ins_UTP( TT_ExecContext  exc,
+           FT_Long*        args )
   {
     FT_UShort  point;
     FT_Byte    mask;
@@ -7220,22 +6748,22 @@
 
     point = (FT_UShort)args[0];
 
-    if ( BOUNDS( point, CUR.zp0.n_points ) )
+    if ( BOUNDS( point, exc->zp0.n_points ) )
     {
-      if ( CUR.pedantic_hinting )
-        CUR.error = FT_THROW( Invalid_Reference );
+      if ( exc->pedantic_hinting )
+        exc->error = FT_THROW( Invalid_Reference );
       return;
     }
 
     mask = 0xFF;
 
-    if ( CUR.GS.freeVector.x != 0 )
+    if ( exc->GS.freeVector.x != 0 )
       mask &= ~FT_CURVE_TAG_TOUCH_X;
 
-    if ( CUR.GS.freeVector.y != 0 )
+    if ( exc->GS.freeVector.y != 0 )
       mask &= ~FT_CURVE_TAG_TOUCH_Y;
 
-    CUR.zp0.tags[point] &= mask;
+    exc->zp0.tags[point] &= mask;
   }
 
 
@@ -7280,7 +6808,7 @@
                            FT_UInt     ref2 )
   {
     FT_UInt     i;
-    FT_F26Dot6  orus1, orus2, org1, org2, delta1, delta2;
+    FT_F26Dot6  orus1, orus2, org1, org2, cur1, cur2, delta1, delta2;
 
 
     if ( p1 > p2 )
@@ -7310,12 +6838,15 @@
 
     org1   = worker->orgs[ref1].x;
     org2   = worker->orgs[ref2].x;
-    delta1 = worker->curs[ref1].x - org1;
-    delta2 = worker->curs[ref2].x - org2;
+    cur1   = worker->curs[ref1].x;
+    cur2   = worker->curs[ref2].x;
+    delta1 = cur1 - org1;
+    delta2 = cur2 - org2;
 
-    if ( orus1 == orus2 )
+    if ( cur1 == cur2 || orus1 == orus2 )
     {
-      /* simple shift of untouched points */
+
+      /* trivial snap or shift of untouched points */
       for ( i = p1; i <= p2; i++ )
       {
         FT_F26Dot6  x = worker->orgs[i].x;
@@ -7323,9 +6854,13 @@
 
         if ( x <= org1 )
           x += delta1;
-        else
+
+        else if ( x >= org2 )
           x += delta2;
 
+        else
+          x = cur1;
+
         worker->curs[i].x = x;
       }
     }
@@ -7352,12 +6887,10 @@
           if ( !scale_valid )
           {
             scale_valid = 1;
-            scale       = FT_DivFix( org2 + delta2 - ( org1 + delta1 ),
-                                     orus2 - orus1 );
+            scale       = FT_DivFix( cur2 - cur1, orus2 - orus1 );
           }
 
-          x = ( org1 + delta1 ) +
-              FT_MulFix( worker->orus[i].x - orus1, scale );
+          x = cur1 + FT_MulFix( worker->orus[i].x - orus1, scale );
         }
         worker->curs[i].x = x;
       }
@@ -7372,7 +6905,7 @@
   /* Stack:        -->                                                     */
   /*                                                                       */
   static void
-  Ins_IUP( INS_ARG )
+  Ins_IUP( TT_ExecContext  exc )
   {
     IUP_WorkerRec  V;
     FT_Byte        mask;
@@ -7386,51 +6919,49 @@
     FT_UInt   point;         /* current point   */
     FT_Short  contour;       /* current contour */
 
-    FT_UNUSED_ARG;
-
 
     /* ignore empty outlines */
-    if ( CUR.pts.n_contours == 0 )
+    if ( exc->pts.n_contours == 0 )
       return;
 
-    if ( CUR.opcode & 1 )
+    if ( exc->opcode & 1 )
     {
       mask   = FT_CURVE_TAG_TOUCH_X;
-      V.orgs = CUR.pts.org;
-      V.curs = CUR.pts.cur;
-      V.orus = CUR.pts.orus;
+      V.orgs = exc->pts.org;
+      V.curs = exc->pts.cur;
+      V.orus = exc->pts.orus;
     }
     else
     {
       mask   = FT_CURVE_TAG_TOUCH_Y;
-      V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 );
-      V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 );
-      V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 );
+      V.orgs = (FT_Vector*)( (FT_Pos*)exc->pts.org + 1 );
+      V.curs = (FT_Vector*)( (FT_Pos*)exc->pts.cur + 1 );
+      V.orus = (FT_Vector*)( (FT_Pos*)exc->pts.orus + 1 );
     }
-    V.max_points = CUR.pts.n_points;
+    V.max_points = exc->pts.n_points;
 
     contour = 0;
     point   = 0;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    if ( SUBPIXEL_HINTING  &&
-         CUR.ignore_x_mode )
+    if ( SUBPIXEL_HINTING   &&
+         exc->ignore_x_mode )
     {
-      CUR.iup_called = TRUE;
-      if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
+      exc->iup_called = TRUE;
+      if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
         return;
     }
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
     do
     {
-      end_point   = CUR.pts.contours[contour] - CUR.pts.first_point;
+      end_point   = exc->pts.contours[contour] - exc->pts.first_point;
       first_point = point;
 
-      if ( BOUNDS ( end_point, CUR.pts.n_points ) )
-        end_point = CUR.pts.n_points - 1;
+      if ( BOUNDS( end_point, exc->pts.n_points ) )
+        end_point = exc->pts.n_points - 1;
 
-      while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 )
+      while ( point <= end_point && ( exc->pts.tags[point] & mask ) == 0 )
         point++;
 
       if ( point <= end_point )
@@ -7442,7 +6973,7 @@
 
         while ( point <= end_point )
         {
-          if ( ( CUR.pts.tags[point] & mask ) != 0 )
+          if ( ( exc->pts.tags[point] & mask ) != 0 )
           {
             _iup_worker_interpolate( &V,
                                      cur_touched + 1,
@@ -7474,7 +7005,7 @@
         }
       }
       contour++;
-    } while ( contour < CUR.pts.n_contours );
+    } while ( contour < exc->pts.n_contours );
   }
 
 
@@ -7485,61 +7016,63 @@
   /* Stack:        uint32 (2 * uint32)... -->                              */
   /*                                                                       */
   static void
-  Ins_DELTAP( INS_ARG )
+  Ins_DELTAP( TT_ExecContext  exc,
+              FT_Long*        args )
   {
-    FT_ULong   k, nump;
+    FT_ULong   nump, k;
     FT_UShort  A;
-    FT_ULong   C;
+    FT_ULong   C, P;
     FT_Long    B;
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     FT_UShort  B1, B2;
 
 
-    if ( SUBPIXEL_HINTING                                        &&
-         CUR.ignore_x_mode                                       &&
-         CUR.iup_called                                          &&
-         ( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
+    if ( SUBPIXEL_HINTING                                         &&
+         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 ( CUR.face->unpatented_hinting )
+    if ( exc->face->unpatented_hinting )
     {
       FT_Long  n = args[0] * 2;
 
 
-      if ( CUR.args < n )
+      if ( exc->args < n )
       {
-        if ( CUR.pedantic_hinting )
-          CUR.error = FT_THROW( Too_Few_Arguments );
-        n = CUR.args;
+        if ( exc->pedantic_hinting )
+          exc->error = FT_THROW( Too_Few_Arguments );
+        n = exc->args;
       }
 
-      CUR.args -= n;
-      CUR.new_top = CUR.args;
+      exc->args -= n;
+      exc->new_top = exc->args;
       return;
     }
 #endif
 
+    P    = (FT_ULong)exc->func_cur_ppem( exc );
     nump = (FT_ULong)args[0];   /* some points theoretically may occur more
                                    than once, thus UShort isn't enough */
 
     for ( k = 1; k <= nump; k++ )
     {
-      if ( CUR.args < 2 )
+      if ( exc->args < 2 )
       {
-        if ( CUR.pedantic_hinting )
-          CUR.error = FT_THROW( Too_Few_Arguments );
-        CUR.args = 0;
+        if ( exc->pedantic_hinting )
+          exc->error = FT_THROW( Too_Few_Arguments );
+        exc->args = 0;
         goto Fail;
       }
 
-      CUR.args -= 2;
+      exc->args -= 2;
 
-      A = (FT_UShort)CUR.stack[CUR.args + 1];
-      B = CUR.stack[CUR.args];
+      A = (FT_UShort)exc->stack[exc->args + 1];
+      B = exc->stack[exc->args];
 
       /* XXX: Because some popular fonts contain some invalid DeltaP */
       /*      instructions, we simply ignore them when the stacked   */
@@ -7547,11 +7080,11 @@
       /*      error.  As a delta instruction doesn't change a glyph  */
       /*      in great ways, this shouldn't be a problem.            */
 
-      if ( !BOUNDS( A, CUR.zp0.n_points ) )
+      if ( !BOUNDS( A, exc->zp0.n_points ) )
       {
         C = ( (FT_ULong)B & 0xF0 ) >> 4;
 
-        switch ( CUR.opcode )
+        switch ( exc->opcode )
         {
         case 0x5D:
           break;
@@ -7565,14 +7098,14 @@
           break;
         }
 
-        C += CUR.GS.delta_base;
+        C += exc->GS.delta_base;
 
-        if ( CURRENT_Ppem() == (FT_Long)C )
+        if ( P == C )
         {
           B = ( (FT_ULong)B & 0xF ) - 8;
           if ( B >= 0 )
             B++;
-          B = B * 64 / ( 1L << CUR.GS.delta_shift );
+          B *= 1L << ( 6 - exc->GS.delta_shift );
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 
@@ -7581,79 +7114,70 @@
             /*
              *  Allow delta move if
              *
-             *  - not using ignore_x_mode rendering
-             *  - glyph is specifically set to allow it
-             *  - glyph is composite and freedom vector is not subpixel
-             *    vector
+             *  - not using ignore_x_mode rendering,
+             *  - glyph is specifically set to allow it, or
+             *  - glyph is composite and freedom vector is not in subpixel
+             *    direction.
              */
-            if ( !CUR.ignore_x_mode                                   ||
-                 ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
-                 ( CUR.is_composite && CUR.GS.freeVector.y != 0 )     )
-              CUR_Func_move( &CUR.zp0, A, B );
+            if ( !exc->ignore_x_mode                                   ||
+                 ( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
+                 ( exc->is_composite && exc->GS.freeVector.y != 0 )    )
+              exc->func_move( exc, &exc->zp0, A, B );
 
-            /* Otherwise apply subpixel hinting and */
-            /* compatibility mode rules             */
-            else if ( CUR.ignore_x_mode )
+            /* Otherwise, apply subpixel hinting and compatibility mode */
+            /* rules, always skipping deltas in subpixel direction.     */
+            else if ( exc->ignore_x_mode && exc->GS.freeVector.y != 0 )
             {
-              if ( CUR.GS.freeVector.y != 0 )
-                B1 = (FT_UShort)CUR.zp0.cur[A].y;
-              else
-                B1 = (FT_UShort)CUR.zp0.cur[A].x;
+              /* save the y value of the point now; compare after move */
+              B1 = (FT_UShort)exc->zp0.cur[A].y;
 
-#if 0
-              /* Standard Subpixel Hinting: Allow y move.       */
-              /* This messes up dejavu and may not be needed... */
-              if ( !CUR.face->sph_compatibility_mode &&
-                   CUR.GS.freeVector.y != 0          )
-                CUR_Func_move( &CUR.zp0, A, B );
-              else
-#endif /* 0 */
+              /* Standard subpixel hinting: Allow y move for y-touched */
+              /* points.  This messes up DejaVu ...                    */
+              if ( !exc->face->sph_compatibility_mode          &&
+                   ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
+                exc->func_move( exc, &exc->zp0, A, B );
 
-              /* Compatibility Mode: Allow x or y move if point touched in */
-              /* Y direction.                                              */
-              if ( CUR.face->sph_compatibility_mode                      &&
-                   !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
+              /* compatibility mode */
+              else if ( exc->face->sph_compatibility_mode                        &&
+                        !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
               {
-                /* save the y value of the point now; compare after move */
-                B1 = (FT_UShort)CUR.zp0.cur[A].y;
-
-                if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
+                if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
                   B = FT_PIX_ROUND( B1 + B ) - B1;
 
                 /* Allow delta move if using sph_compatibility_mode,   */
                 /* IUP has not been called, and point is touched on Y. */
-                if ( !CUR.iup_called                            &&
-                     ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
-                  CUR_Func_move( &CUR.zp0, A, B );
+                if ( !exc->iup_called                            &&
+                     ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
+                  exc->func_move( exc, &exc->zp0, A, B );
               }
 
-              B2 = (FT_UShort)CUR.zp0.cur[A].y;
+              B2 = (FT_UShort)exc->zp0.cur[A].y;
 
               /* Reverse this move if it results in a disallowed move */
-              if ( CUR.GS.freeVector.y != 0                           &&
-                   ( ( CUR.face->sph_compatibility_mode           &&
+              if ( exc->GS.freeVector.y != 0                          &&
+                   ( ( exc->face->sph_compatibility_mode          &&
                        ( B1 & 63 ) == 0                           &&
                        ( B2 & 63 ) != 0                           ) ||
-                     ( ( CUR.sph_tweak_flags                    &
+                     ( ( exc->sph_tweak_flags                   &
                          SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) &&
                        ( B1 & 63 ) != 0                           &&
                        ( B2 & 63 ) != 0                           ) ) )
-                CUR_Func_move( &CUR.zp0, A, -B );
+                exc->func_move( exc, &exc->zp0, A, -B );
             }
           }
           else
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-            CUR_Func_move( &CUR.zp0, A, B );
+            exc->func_move( exc, &exc->zp0, A, B );
         }
       }
       else
-        if ( CUR.pedantic_hinting )
-          CUR.error = FT_THROW( Invalid_Reference );
+        if ( exc->pedantic_hinting )
+          exc->error = FT_THROW( Invalid_Reference );
     }
 
   Fail:
-    CUR.new_top = CUR.args;
+    exc->new_top = exc->args;
   }
 
 
@@ -7664,55 +7188,57 @@
   /* Stack:        uint32 (2 * uint32)... -->                              */
   /*                                                                       */
   static void
-  Ins_DELTAC( INS_ARG )
+  Ins_DELTAC( TT_ExecContext  exc,
+              FT_Long*        args )
   {
     FT_ULong  nump, k;
-    FT_ULong  A, C;
+    FT_ULong  A, C, P;
     FT_Long   B;
 
 
 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
     /* Delta hinting is covered by US Patent 5159668. */
-    if ( CUR.face->unpatented_hinting )
+    if ( exc->face->unpatented_hinting )
     {
       FT_Long  n = args[0] * 2;
 
 
-      if ( CUR.args < n )
+      if ( exc->args < n )
       {
-        if ( CUR.pedantic_hinting )
-          CUR.error = FT_THROW( Too_Few_Arguments );
-        n = CUR.args;
+        if ( exc->pedantic_hinting )
+          exc->error = FT_THROW( Too_Few_Arguments );
+        n = exc->args;
       }
 
-      CUR.args -= n;
-      CUR.new_top = CUR.args;
+      exc->args -= n;
+      exc->new_top = exc->args;
       return;
     }
 #endif
 
+    P    = (FT_ULong)exc->func_cur_ppem( exc );
     nump = (FT_ULong)args[0];
 
     for ( k = 1; k <= nump; k++ )
     {
-      if ( CUR.args < 2 )
+      if ( exc->args < 2 )
       {
-        if ( CUR.pedantic_hinting )
-          CUR.error = FT_THROW( Too_Few_Arguments );
-        CUR.args = 0;
+        if ( exc->pedantic_hinting )
+          exc->error = FT_THROW( Too_Few_Arguments );
+        exc->args = 0;
         goto Fail;
       }
 
-      CUR.args -= 2;
+      exc->args -= 2;
 
-      A = (FT_ULong)CUR.stack[CUR.args + 1];
-      B = CUR.stack[CUR.args];
+      A = (FT_ULong)exc->stack[exc->args + 1];
+      B = exc->stack[exc->args];
 
-      if ( BOUNDSL( A, CUR.cvtSize ) )
+      if ( BOUNDSL( A, exc->cvtSize ) )
       {
-        if ( CUR.pedantic_hinting )
+        if ( exc->pedantic_hinting )
         {
-          CUR.error = FT_THROW( Invalid_Reference );
+          exc->error = FT_THROW( Invalid_Reference );
           return;
         }
       }
@@ -7720,7 +7246,7 @@
       {
         C = ( (FT_ULong)B & 0xF0 ) >> 4;
 
-        switch ( CUR.opcode )
+        switch ( exc->opcode )
         {
         case 0x73:
           break;
@@ -7734,22 +7260,22 @@
           break;
         }
 
-        C += CUR.GS.delta_base;
+        C += exc->GS.delta_base;
 
-        if ( CURRENT_Ppem() == (FT_Long)C )
+        if ( P == C )
         {
           B = ( (FT_ULong)B & 0xF ) - 8;
           if ( B >= 0 )
             B++;
-          B = B * 64 / ( 1L << CUR.GS.delta_shift );
+          B *= 1L << ( 6 - exc->GS.delta_shift );
 
-          CUR_Func_move_cvt( A, B );
+          exc->func_move_cvt( exc, A, B );
         }
       }
     }
 
   Fail:
-    CUR.new_top = CUR.args;
+    exc->new_top = exc->args;
   }
 
 
@@ -7766,8 +7292,17 @@
   /* Opcode range: 0x88                                                    */
   /* Stack:        uint32 --> uint32                                       */
   /*                                                                       */
+  /* XXX: UNDOCUMENTED: Selector bits higher than 9 are currently (May     */
+  /*      2015) not documented in the OpenType specification.              */
+  /*                                                                       */
+  /*      Selector bit 11 is incorrectly described as bit 8, while the     */
+  /*      real meaning of bit 8 (vertical LCD subpixels) stays             */
+  /*      undocumented.  The same mistake can be found in Greg Hitchcock's */
+  /*      whitepaper.                                                      */
+  /*                                                                       */
   static void
-  Ins_GETINFO( INS_ARG )
+  Ins_GETINFO( TT_ExecContext  exc,
+               FT_Long*        args )
   {
     FT_Long  K;
 
@@ -7780,13 +7315,20 @@
     /* Selector Bit:  0             */
     /* Return Bit(s): 0-7           */
     /*                              */
-    if ( SUBPIXEL_HINTING     &&
-         ( args[0] & 1 ) != 0 &&
-         CUR.ignore_x_mode    )
+    if ( SUBPIXEL_HINTING      &&
+         ( args[0] & 1 ) != 0  &&
+         exc->subpixel_hinting )
     {
-      K = CUR.rasterizer_version;
-      FT_TRACE7(( "Setting rasterizer version %d\n",
-                  CUR.rasterizer_version ));
+      if ( exc->ignore_x_mode )
+      {
+        /* if in ClearType backwards compatibility mode,        */
+        /* we sometimes change the TrueType version dynamically */
+        K = exc->rasterizer_version;
+        FT_TRACE6(( "Setting rasterizer version %d\n",
+                    exc->rasterizer_version ));
+      }
+      else
+        K = TT_INTERPRETER_VERSION_38;
     }
     else
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
@@ -7798,7 +7340,7 @@
     /* Selector Bit:  1             */
     /* Return Bit(s): 8             */
     /*                              */
-    if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated )
+    if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated )
       K |= 0x80;
 
     /********************************/
@@ -7806,7 +7348,7 @@
     /* Selector Bit:  2             */
     /* Return Bit(s): 9             */
     /*                              */
-    if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched )
+    if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched )
       K |= 1 << 8;
 
     /********************************/
@@ -7814,24 +7356,23 @@
     /* Selector Bit:  5             */
     /* Return Bit(s): 12            */
     /*                              */
-    if ( ( args[0] & 32 ) != 0 && CUR.grayscale )
+    if ( ( args[0] & 32 ) != 0 && exc->grayscale )
       K |= 1 << 12;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 
-    if ( SUBPIXEL_HINTING                                    &&
-         CUR.ignore_x_mode                                   &&
-         CUR.rasterizer_version >= TT_INTERPRETER_VERSION_35 )
+    if ( SUBPIXEL_HINTING                                     &&
+         exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 )
     {
 
-      if ( CUR.rasterizer_version >= 37 )
+      if ( exc->rasterizer_version >= 37 )
       {
         /********************************/
         /* HINTING FOR SUBPIXEL         */
         /* Selector Bit:  6             */
         /* Return Bit(s): 13            */
         /*                              */
-        if ( ( args[0] & 64 ) != 0 && CUR.subpixel )
+        if ( ( args[0] & 64 ) != 0 && exc->subpixel_hinting )
           K |= 1 << 13;
 
         /********************************/
@@ -7840,16 +7381,16 @@
         /* Return Bit(s): 14            */
         /*                              */
         /* Functionality still needs to be added */
-        if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths )
+        if ( ( args[0] & 128 ) != 0 && exc->compatible_widths )
           K |= 1 << 14;
 
         /********************************/
-        /* SYMMETRICAL SMOOTHING        */
+        /* VERTICAL LCD SUBPIXELS?      */
         /* Selector Bit:  8             */
         /* Return Bit(s): 15            */
         /*                              */
         /* Functionality still needs to be added */
-        if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing )
+        if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd )
           K |= 1 << 15;
 
         /********************************/
@@ -7858,10 +7399,10 @@
         /* Return Bit(s): 16            */
         /*                              */
         /* Functionality still needs to be added */
-        if ( ( args[0] & 512 ) != 0 && CUR.bgr )
+        if ( ( args[0] & 512 ) != 0 && exc->bgr )
           K |= 1 << 16;
 
-        if ( CUR.rasterizer_version >= 38 )
+        if ( exc->rasterizer_version >= 38 )
         {
           /********************************/
           /* SUBPIXEL POSITIONED?         */
@@ -7869,8 +7410,26 @@
           /* Return Bit(s): 17            */
           /*                              */
           /* Functionality still needs to be added */
-          if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned )
+          if ( ( args[0] & 1024 ) != 0 && exc->subpixel_positioned )
             K |= 1 << 17;
+
+          /********************************/
+          /* SYMMETRICAL SMOOTHING        */
+          /* Selector Bit:  11            */
+          /* Return Bit(s): 18            */
+          /*                              */
+          /* Functionality still needs to be added */
+          if ( ( args[0] & 2048 ) != 0 && exc->symmetrical_smoothing )
+            K |= 1 << 18;
+
+          /********************************/
+          /* GRAY CLEARTYPE               */
+          /* Selector Bit:  12            */
+          /* Return Bit(s): 19            */
+          /*                              */
+          /* Functionality still needs to be added */
+          if ( ( args[0] & 4096 ) != 0 && exc->gray_cleartype )
+            K |= 1 << 19;
         }
       }
     }
@@ -7882,331 +7441,43 @@
 
 
   static void
-  Ins_UNKNOWN( INS_ARG )
+  Ins_UNKNOWN( TT_ExecContext  exc )
   {
-    TT_DefRecord*  def   = CUR.IDefs;
-    TT_DefRecord*  limit = def + CUR.numIDefs;
-
-    FT_UNUSED_ARG;
+    TT_DefRecord*  def   = exc->IDefs;
+    TT_DefRecord*  limit = def + exc->numIDefs;
 
 
     for ( ; def < limit; def++ )
     {
-      if ( (FT_Byte)def->opc == CUR.opcode && def->active )
+      if ( (FT_Byte)def->opc == exc->opcode && def->active )
       {
         TT_CallRec*  call;
 
 
-        if ( CUR.callTop >= CUR.callSize )
+        if ( exc->callTop >= exc->callSize )
         {
-          CUR.error = FT_THROW( Stack_Overflow );
+          exc->error = FT_THROW( Stack_Overflow );
           return;
         }
 
-        call = CUR.callStack + CUR.callTop++;
+        call = exc->callStack + exc->callTop++;
 
-        call->Caller_Range = CUR.curRange;
-        call->Caller_IP    = CUR.IP + 1;
+        call->Caller_Range = exc->curRange;
+        call->Caller_IP    = exc->IP + 1;
         call->Cur_Count    = 1;
         call->Def          = def;
 
-        INS_Goto_CodeRange( def->range, def->start );
+        Ins_Goto_CodeRange( exc, def->range, def->start );
 
-        CUR.step_ins = FALSE;
+        exc->step_ins = FALSE;
         return;
       }
     }
 
-    CUR.error = FT_THROW( Invalid_Opcode );
+    exc->error = FT_THROW( Invalid_Opcode );
   }
 
 
-#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
-
-
-  static
-  TInstruction_Function  Instruct_Dispatch[256] =
-  {
-    /* Opcodes are gathered in groups of 16. */
-    /* Please keep the spaces as they are.   */
-
-    /*  SVTCA  y  */  Ins_SVTCA,
-    /*  SVTCA  x  */  Ins_SVTCA,
-    /*  SPvTCA y  */  Ins_SPVTCA,
-    /*  SPvTCA x  */  Ins_SPVTCA,
-    /*  SFvTCA y  */  Ins_SFVTCA,
-    /*  SFvTCA x  */  Ins_SFVTCA,
-    /*  SPvTL //  */  Ins_SPVTL,
-    /*  SPvTL +   */  Ins_SPVTL,
-    /*  SFvTL //  */  Ins_SFVTL,
-    /*  SFvTL +   */  Ins_SFVTL,
-    /*  SPvFS     */  Ins_SPVFS,
-    /*  SFvFS     */  Ins_SFVFS,
-    /*  GPV       */  Ins_GPV,
-    /*  GFV       */  Ins_GFV,
-    /*  SFvTPv    */  Ins_SFVTPV,
-    /*  ISECT     */  Ins_ISECT,
-
-    /*  SRP0      */  Ins_SRP0,
-    /*  SRP1      */  Ins_SRP1,
-    /*  SRP2      */  Ins_SRP2,
-    /*  SZP0      */  Ins_SZP0,
-    /*  SZP1      */  Ins_SZP1,
-    /*  SZP2      */  Ins_SZP2,
-    /*  SZPS      */  Ins_SZPS,
-    /*  SLOOP     */  Ins_SLOOP,
-    /*  RTG       */  Ins_RTG,
-    /*  RTHG      */  Ins_RTHG,
-    /*  SMD       */  Ins_SMD,
-    /*  ELSE      */  Ins_ELSE,
-    /*  JMPR      */  Ins_JMPR,
-    /*  SCvTCi    */  Ins_SCVTCI,
-    /*  SSwCi     */  Ins_SSWCI,
-    /*  SSW       */  Ins_SSW,
-
-    /*  DUP       */  Ins_DUP,
-    /*  POP       */  Ins_POP,
-    /*  CLEAR     */  Ins_CLEAR,
-    /*  SWAP      */  Ins_SWAP,
-    /*  DEPTH     */  Ins_DEPTH,
-    /*  CINDEX    */  Ins_CINDEX,
-    /*  MINDEX    */  Ins_MINDEX,
-    /*  AlignPTS  */  Ins_ALIGNPTS,
-    /*  INS_0x28  */  Ins_UNKNOWN,
-    /*  UTP       */  Ins_UTP,
-    /*  LOOPCALL  */  Ins_LOOPCALL,
-    /*  CALL      */  Ins_CALL,
-    /*  FDEF      */  Ins_FDEF,
-    /*  ENDF      */  Ins_ENDF,
-    /*  MDAP[0]   */  Ins_MDAP,
-    /*  MDAP[1]   */  Ins_MDAP,
-
-    /*  IUP[0]    */  Ins_IUP,
-    /*  IUP[1]    */  Ins_IUP,
-    /*  SHP[0]    */  Ins_SHP,
-    /*  SHP[1]    */  Ins_SHP,
-    /*  SHC[0]    */  Ins_SHC,
-    /*  SHC[1]    */  Ins_SHC,
-    /*  SHZ[0]    */  Ins_SHZ,
-    /*  SHZ[1]    */  Ins_SHZ,
-    /*  SHPIX     */  Ins_SHPIX,
-    /*  IP        */  Ins_IP,
-    /*  MSIRP[0]  */  Ins_MSIRP,
-    /*  MSIRP[1]  */  Ins_MSIRP,
-    /*  AlignRP   */  Ins_ALIGNRP,
-    /*  RTDG      */  Ins_RTDG,
-    /*  MIAP[0]   */  Ins_MIAP,
-    /*  MIAP[1]   */  Ins_MIAP,
-
-    /*  NPushB    */  Ins_NPUSHB,
-    /*  NPushW    */  Ins_NPUSHW,
-    /*  WS        */  Ins_WS,
-    /*  RS        */  Ins_RS,
-    /*  WCvtP     */  Ins_WCVTP,
-    /*  RCvt      */  Ins_RCVT,
-    /*  GC[0]     */  Ins_GC,
-    /*  GC[1]     */  Ins_GC,
-    /*  SCFS      */  Ins_SCFS,
-    /*  MD[0]     */  Ins_MD,
-    /*  MD[1]     */  Ins_MD,
-    /*  MPPEM     */  Ins_MPPEM,
-    /*  MPS       */  Ins_MPS,
-    /*  FlipON    */  Ins_FLIPON,
-    /*  FlipOFF   */  Ins_FLIPOFF,
-    /*  DEBUG     */  Ins_DEBUG,
-
-    /*  LT        */  Ins_LT,
-    /*  LTEQ      */  Ins_LTEQ,
-    /*  GT        */  Ins_GT,
-    /*  GTEQ      */  Ins_GTEQ,
-    /*  EQ        */  Ins_EQ,
-    /*  NEQ       */  Ins_NEQ,
-    /*  ODD       */  Ins_ODD,
-    /*  EVEN      */  Ins_EVEN,
-    /*  IF        */  Ins_IF,
-    /*  EIF       */  Ins_EIF,
-    /*  AND       */  Ins_AND,
-    /*  OR        */  Ins_OR,
-    /*  NOT       */  Ins_NOT,
-    /*  DeltaP1   */  Ins_DELTAP,
-    /*  SDB       */  Ins_SDB,
-    /*  SDS       */  Ins_SDS,
-
-    /*  ADD       */  Ins_ADD,
-    /*  SUB       */  Ins_SUB,
-    /*  DIV       */  Ins_DIV,
-    /*  MUL       */  Ins_MUL,
-    /*  ABS       */  Ins_ABS,
-    /*  NEG       */  Ins_NEG,
-    /*  FLOOR     */  Ins_FLOOR,
-    /*  CEILING   */  Ins_CEILING,
-    /*  ROUND[0]  */  Ins_ROUND,
-    /*  ROUND[1]  */  Ins_ROUND,
-    /*  ROUND[2]  */  Ins_ROUND,
-    /*  ROUND[3]  */  Ins_ROUND,
-    /*  NROUND[0] */  Ins_NROUND,
-    /*  NROUND[1] */  Ins_NROUND,
-    /*  NROUND[2] */  Ins_NROUND,
-    /*  NROUND[3] */  Ins_NROUND,
-
-    /*  WCvtF     */  Ins_WCVTF,
-    /*  DeltaP2   */  Ins_DELTAP,
-    /*  DeltaP3   */  Ins_DELTAP,
-    /*  DeltaCn[0] */ Ins_DELTAC,
-    /*  DeltaCn[1] */ Ins_DELTAC,
-    /*  DeltaCn[2] */ Ins_DELTAC,
-    /*  SROUND    */  Ins_SROUND,
-    /*  S45Round  */  Ins_S45ROUND,
-    /*  JROT      */  Ins_JROT,
-    /*  JROF      */  Ins_JROF,
-    /*  ROFF      */  Ins_ROFF,
-    /*  INS_0x7B  */  Ins_UNKNOWN,
-    /*  RUTG      */  Ins_RUTG,
-    /*  RDTG      */  Ins_RDTG,
-    /*  SANGW     */  Ins_SANGW,
-    /*  AA        */  Ins_AA,
-
-    /*  FlipPT    */  Ins_FLIPPT,
-    /*  FlipRgON  */  Ins_FLIPRGON,
-    /*  FlipRgOFF */  Ins_FLIPRGOFF,
-    /*  INS_0x83  */  Ins_UNKNOWN,
-    /*  INS_0x84  */  Ins_UNKNOWN,
-    /*  ScanCTRL  */  Ins_SCANCTRL,
-    /*  SDPVTL[0] */  Ins_SDPVTL,
-    /*  SDPVTL[1] */  Ins_SDPVTL,
-    /*  GetINFO   */  Ins_GETINFO,
-    /*  IDEF      */  Ins_IDEF,
-    /*  ROLL      */  Ins_ROLL,
-    /*  MAX       */  Ins_MAX,
-    /*  MIN       */  Ins_MIN,
-    /*  ScanTYPE  */  Ins_SCANTYPE,
-    /*  InstCTRL  */  Ins_INSTCTRL,
-    /*  INS_0x8F  */  Ins_UNKNOWN,
-
-    /*  INS_0x90  */   Ins_UNKNOWN,
-    /*  INS_0x91  */   Ins_UNKNOWN,
-    /*  INS_0x92  */   Ins_UNKNOWN,
-    /*  INS_0x93  */   Ins_UNKNOWN,
-    /*  INS_0x94  */   Ins_UNKNOWN,
-    /*  INS_0x95  */   Ins_UNKNOWN,
-    /*  INS_0x96  */   Ins_UNKNOWN,
-    /*  INS_0x97  */   Ins_UNKNOWN,
-    /*  INS_0x98  */   Ins_UNKNOWN,
-    /*  INS_0x99  */   Ins_UNKNOWN,
-    /*  INS_0x9A  */   Ins_UNKNOWN,
-    /*  INS_0x9B  */   Ins_UNKNOWN,
-    /*  INS_0x9C  */   Ins_UNKNOWN,
-    /*  INS_0x9D  */   Ins_UNKNOWN,
-    /*  INS_0x9E  */   Ins_UNKNOWN,
-    /*  INS_0x9F  */   Ins_UNKNOWN,
-
-    /*  INS_0xA0  */   Ins_UNKNOWN,
-    /*  INS_0xA1  */   Ins_UNKNOWN,
-    /*  INS_0xA2  */   Ins_UNKNOWN,
-    /*  INS_0xA3  */   Ins_UNKNOWN,
-    /*  INS_0xA4  */   Ins_UNKNOWN,
-    /*  INS_0xA5  */   Ins_UNKNOWN,
-    /*  INS_0xA6  */   Ins_UNKNOWN,
-    /*  INS_0xA7  */   Ins_UNKNOWN,
-    /*  INS_0xA8  */   Ins_UNKNOWN,
-    /*  INS_0xA9  */   Ins_UNKNOWN,
-    /*  INS_0xAA  */   Ins_UNKNOWN,
-    /*  INS_0xAB  */   Ins_UNKNOWN,
-    /*  INS_0xAC  */   Ins_UNKNOWN,
-    /*  INS_0xAD  */   Ins_UNKNOWN,
-    /*  INS_0xAE  */   Ins_UNKNOWN,
-    /*  INS_0xAF  */   Ins_UNKNOWN,
-
-    /*  PushB[0]  */  Ins_PUSHB,
-    /*  PushB[1]  */  Ins_PUSHB,
-    /*  PushB[2]  */  Ins_PUSHB,
-    /*  PushB[3]  */  Ins_PUSHB,
-    /*  PushB[4]  */  Ins_PUSHB,
-    /*  PushB[5]  */  Ins_PUSHB,
-    /*  PushB[6]  */  Ins_PUSHB,
-    /*  PushB[7]  */  Ins_PUSHB,
-    /*  PushW[0]  */  Ins_PUSHW,
-    /*  PushW[1]  */  Ins_PUSHW,
-    /*  PushW[2]  */  Ins_PUSHW,
-    /*  PushW[3]  */  Ins_PUSHW,
-    /*  PushW[4]  */  Ins_PUSHW,
-    /*  PushW[5]  */  Ins_PUSHW,
-    /*  PushW[6]  */  Ins_PUSHW,
-    /*  PushW[7]  */  Ins_PUSHW,
-
-    /*  MDRP[00]  */  Ins_MDRP,
-    /*  MDRP[01]  */  Ins_MDRP,
-    /*  MDRP[02]  */  Ins_MDRP,
-    /*  MDRP[03]  */  Ins_MDRP,
-    /*  MDRP[04]  */  Ins_MDRP,
-    /*  MDRP[05]  */  Ins_MDRP,
-    /*  MDRP[06]  */  Ins_MDRP,
-    /*  MDRP[07]  */  Ins_MDRP,
-    /*  MDRP[08]  */  Ins_MDRP,
-    /*  MDRP[09]  */  Ins_MDRP,
-    /*  MDRP[10]  */  Ins_MDRP,
-    /*  MDRP[11]  */  Ins_MDRP,
-    /*  MDRP[12]  */  Ins_MDRP,
-    /*  MDRP[13]  */  Ins_MDRP,
-    /*  MDRP[14]  */  Ins_MDRP,
-    /*  MDRP[15]  */  Ins_MDRP,
-
-    /*  MDRP[16]  */  Ins_MDRP,
-    /*  MDRP[17]  */  Ins_MDRP,
-    /*  MDRP[18]  */  Ins_MDRP,
-    /*  MDRP[19]  */  Ins_MDRP,
-    /*  MDRP[20]  */  Ins_MDRP,
-    /*  MDRP[21]  */  Ins_MDRP,
-    /*  MDRP[22]  */  Ins_MDRP,
-    /*  MDRP[23]  */  Ins_MDRP,
-    /*  MDRP[24]  */  Ins_MDRP,
-    /*  MDRP[25]  */  Ins_MDRP,
-    /*  MDRP[26]  */  Ins_MDRP,
-    /*  MDRP[27]  */  Ins_MDRP,
-    /*  MDRP[28]  */  Ins_MDRP,
-    /*  MDRP[29]  */  Ins_MDRP,
-    /*  MDRP[30]  */  Ins_MDRP,
-    /*  MDRP[31]  */  Ins_MDRP,
-
-    /*  MIRP[00]  */  Ins_MIRP,
-    /*  MIRP[01]  */  Ins_MIRP,
-    /*  MIRP[02]  */  Ins_MIRP,
-    /*  MIRP[03]  */  Ins_MIRP,
-    /*  MIRP[04]  */  Ins_MIRP,
-    /*  MIRP[05]  */  Ins_MIRP,
-    /*  MIRP[06]  */  Ins_MIRP,
-    /*  MIRP[07]  */  Ins_MIRP,
-    /*  MIRP[08]  */  Ins_MIRP,
-    /*  MIRP[09]  */  Ins_MIRP,
-    /*  MIRP[10]  */  Ins_MIRP,
-    /*  MIRP[11]  */  Ins_MIRP,
-    /*  MIRP[12]  */  Ins_MIRP,
-    /*  MIRP[13]  */  Ins_MIRP,
-    /*  MIRP[14]  */  Ins_MIRP,
-    /*  MIRP[15]  */  Ins_MIRP,
-
-    /*  MIRP[16]  */  Ins_MIRP,
-    /*  MIRP[17]  */  Ins_MIRP,
-    /*  MIRP[18]  */  Ins_MIRP,
-    /*  MIRP[19]  */  Ins_MIRP,
-    /*  MIRP[20]  */  Ins_MIRP,
-    /*  MIRP[21]  */  Ins_MIRP,
-    /*  MIRP[22]  */  Ins_MIRP,
-    /*  MIRP[23]  */  Ins_MIRP,
-    /*  MIRP[24]  */  Ins_MIRP,
-    /*  MIRP[25]  */  Ins_MIRP,
-    /*  MIRP[26]  */  Ins_MIRP,
-    /*  MIRP[27]  */  Ins_MIRP,
-    /*  MIRP[28]  */  Ins_MIRP,
-    /*  MIRP[29]  */  Ins_MIRP,
-    /*  MIRP[30]  */  Ins_MIRP,
-    /*  MIRP[31]  */  Ins_MIRP
-  };
-
-
-#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
-
-
   /*************************************************************************/
   /*                                                                       */
   /* RUN                                                                   */
@@ -8234,8 +7505,6 @@
   /*                                                                       */
   /* THIS IS THE INTERPRETER'S MAIN LOOP.                                  */
   /*                                                                       */
-  /*  Instructions appear in the specification's order.                    */
-  /*                                                                       */
   /*************************************************************************/
 
 
@@ -8261,85 +7530,100 @@
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
 
-#ifdef TT_CONFIG_OPTION_STATIC_RASTER
-    cur = *exc;
-#endif
-
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    CUR.iup_called = FALSE;
+    exc->iup_called = FALSE;
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-    /* set CVT functions */
-    CUR.tt_metrics.ratio = 0;
-    if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem )
+    /* set PPEM and CVT functions */
+    exc->tt_metrics.ratio = 0;
+    if ( exc->metrics.x_ppem != exc->metrics.y_ppem )
     {
       /* non-square pixels, use the stretched routines */
-      CUR.func_read_cvt  = Read_CVT_Stretched;
-      CUR.func_write_cvt = Write_CVT_Stretched;
-      CUR.func_move_cvt  = Move_CVT_Stretched;
+      exc->func_cur_ppem  = Current_Ppem_Stretched;
+      exc->func_read_cvt  = Read_CVT_Stretched;
+      exc->func_write_cvt = Write_CVT_Stretched;
+      exc->func_move_cvt  = Move_CVT_Stretched;
     }
     else
     {
       /* square pixels, use normal routines */
-      CUR.func_read_cvt  = Read_CVT;
-      CUR.func_write_cvt = Write_CVT;
-      CUR.func_move_cvt  = Move_CVT;
+      exc->func_cur_ppem  = Current_Ppem;
+      exc->func_read_cvt  = Read_CVT;
+      exc->func_write_cvt = Write_CVT;
+      exc->func_move_cvt  = Move_CVT;
     }
 
-    COMPUTE_Funcs();
-    COMPUTE_Round( (FT_Byte)exc->GS.round_state );
+    Compute_Funcs( exc );
+    Compute_Round( exc, (FT_Byte)exc->GS.round_state );
 
     do
     {
-      CUR.opcode = CUR.code[CUR.IP];
+      exc->opcode = exc->code[exc->IP];
 
-      FT_TRACE7(( "  " ));
-      FT_TRACE7(( opcode_name[CUR.opcode] ));
-      FT_TRACE7(( "\n" ));
-
-      if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 )
+#ifdef FT_DEBUG_LEVEL_TRACE
       {
-        if ( CUR.IP + 1 >= CUR.codeSize )
+        FT_Long  cnt = FT_MIN( 8, exc->top );
+        FT_Long  n;
+
+
+        /* if tracing level is 7, show current code position */
+        /* and the first few stack elements also             */
+        FT_TRACE6(( "  " ));
+        FT_TRACE7(( "%06d ", exc->IP ));
+        FT_TRACE6(( opcode_name[exc->opcode] + 2 ));
+        FT_TRACE7(( "%*s", *opcode_name[exc->opcode] == 'A'
+                              ? 2
+                              : 12 - ( *opcode_name[exc->opcode] - '0' ),
+                              "#" ));
+        for ( n = 0; n < cnt; n++ )
+          FT_TRACE7(( " %d", exc->stack[exc->top - n] ));
+        FT_TRACE6(( "\n" ));
+      }
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
+      if ( ( exc->length = opcode_length[exc->opcode] ) < 0 )
+      {
+        if ( exc->IP + 1 >= exc->codeSize )
           goto LErrorCodeOverflow_;
 
-        CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];
+        exc->length = 2 - exc->length * exc->code[exc->IP + 1];
       }
 
-      if ( CUR.IP + CUR.length > CUR.codeSize )
+      if ( exc->IP + exc->length > exc->codeSize )
         goto LErrorCodeOverflow_;
 
       /* First, let's check for empty stack and overflow */
-      CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 );
+      exc->args = exc->top - ( Pop_Push_Count[exc->opcode] >> 4 );
 
       /* `args' is the top of the stack once arguments have been popped. */
       /* One can also interpret it as the index of the last argument.    */
-      if ( CUR.args < 0 )
+      if ( exc->args < 0 )
       {
-        if ( CUR.pedantic_hinting )
+        if ( exc->pedantic_hinting )
         {
-          CUR.error = FT_THROW( Too_Few_Arguments );
+          exc->error = FT_THROW( Too_Few_Arguments );
           goto LErrorLabel_;
         }
 
         /* push zeroes onto the stack */
-        for ( i = 0; i < Pop_Push_Count[CUR.opcode] >> 4; i++ )
-          CUR.stack[i] = 0;
-        CUR.args = 0;
+        for ( i = 0; i < Pop_Push_Count[exc->opcode] >> 4; i++ )
+          exc->stack[i] = 0;
+        exc->args = 0;
       }
 
-      CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 );
+      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'  */
       /* statement.                                                     */
-      if ( CUR.new_top > CUR.stackSize )
+      if ( exc->new_top > exc->stackSize )
       {
-        CUR.error = FT_THROW( Stack_Overflow );
+        exc->error = FT_THROW( Stack_Overflow );
         goto LErrorLabel_;
       }
 
-      CUR.step_ins = TRUE;
-      CUR.error    = FT_Err_Ok;
+      exc->step_ins = TRUE;
+      exc->error    = FT_Err_Ok;
 
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
 
@@ -8347,17 +7631,17 @@
       {
         for ( i = 0; i < opcode_patterns; i++ )
         {
-          if ( opcode_pointer[i] < opcode_size[i]                 &&
-               CUR.opcode == opcode_pattern[i][opcode_pointer[i]] )
+          if ( opcode_pointer[i] < opcode_size[i]                  &&
+               exc->opcode == opcode_pattern[i][opcode_pointer[i]] )
           {
             opcode_pointer[i] += 1;
 
             if ( opcode_pointer[i] == opcode_size[i] )
             {
-              FT_TRACE7(( "sph: opcode ptrn: %d, %s %s\n",
+              FT_TRACE6(( "sph: opcode ptrn: %d, %s %s\n",
                           i,
-                          CUR.face->root.family_name,
-                          CUR.face->root.style_name ));
+                          exc->face->root.family_name,
+                          exc->face->root.style_name ));
 
               switch ( i )
               {
@@ -8374,15 +7658,9 @@
 
 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
 
-#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH
-
       {
-        FT_Long*  args   = CUR.stack + CUR.args;
-        FT_Byte   opcode = CUR.opcode;
-
-
-#undef  ARRAY_BOUND_ERROR
-#define ARRAY_BOUND_ERROR  goto Set_Invalid_Ref
+        FT_Long*  args   = exc->stack + exc->args;
+        FT_Byte   opcode = exc->opcode;
 
 
         switch ( opcode )
@@ -8393,580 +7671,543 @@
         case 0x03:  /* SPvTCA x */
         case 0x04:  /* SFvTCA y */
         case 0x05:  /* SFvTCA x */
-          {
-            FT_Short  AA, BB;
-
-
-            AA = (FT_Short)( ( opcode & 1 ) << 14 );
-            BB = (FT_Short)( AA ^ 0x4000 );
-
-            if ( opcode < 4 )
-            {
-              CUR.GS.projVector.x = AA;
-              CUR.GS.projVector.y = BB;
-
-              CUR.GS.dualVector.x = AA;
-              CUR.GS.dualVector.y = BB;
-            }
-            else
-            {
-              GUESS_VECTOR( projVector );
-            }
-
-            if ( ( opcode & 2 ) == 0 )
-            {
-              CUR.GS.freeVector.x = AA;
-              CUR.GS.freeVector.y = BB;
-            }
-            else
-            {
-              GUESS_VECTOR( freeVector );
-            }
-
-            COMPUTE_Funcs();
-          }
+          Ins_SxyTCA( exc );
           break;
 
         case 0x06:  /* SPvTL // */
         case 0x07:  /* SPvTL +  */
-          DO_SPVTL
+          Ins_SPVTL( exc, args );
           break;
 
         case 0x08:  /* SFvTL // */
         case 0x09:  /* SFvTL +  */
-          DO_SFVTL
+          Ins_SFVTL( exc, args );
           break;
 
         case 0x0A:  /* SPvFS */
-          DO_SPVFS
+          Ins_SPVFS( exc, args );
           break;
 
         case 0x0B:  /* SFvFS */
-          DO_SFVFS
+          Ins_SFVFS( exc, args );
           break;
 
-        case 0x0C:  /* GPV */
-          DO_GPV
+        case 0x0C:  /* GPv */
+          Ins_GPV( exc, args );
           break;
 
-        case 0x0D:  /* GFV */
-          DO_GFV
+        case 0x0D:  /* GFv */
+          Ins_GFV( exc, args );
           break;
 
         case 0x0E:  /* SFvTPv */
-          DO_SFVTPV
+          Ins_SFVTPV( exc );
           break;
 
         case 0x0F:  /* ISECT  */
-          Ins_ISECT( EXEC_ARG_ args );
+          Ins_ISECT( exc, args );
           break;
 
         case 0x10:  /* SRP0 */
-          DO_SRP0
+          Ins_SRP0( exc, args );
           break;
 
         case 0x11:  /* SRP1 */
-          DO_SRP1
+          Ins_SRP1( exc, args );
           break;
 
         case 0x12:  /* SRP2 */
-          DO_SRP2
+          Ins_SRP2( exc, args );
           break;
 
         case 0x13:  /* SZP0 */
-          Ins_SZP0( EXEC_ARG_ args );
+          Ins_SZP0( exc, args );
           break;
 
         case 0x14:  /* SZP1 */
-          Ins_SZP1( EXEC_ARG_ args );
+          Ins_SZP1( exc, args );
           break;
 
         case 0x15:  /* SZP2 */
-          Ins_SZP2( EXEC_ARG_ args );
+          Ins_SZP2( exc, args );
           break;
 
         case 0x16:  /* SZPS */
-          Ins_SZPS( EXEC_ARG_ args );
+          Ins_SZPS( exc, args );
           break;
 
         case 0x17:  /* SLOOP */
-          DO_SLOOP
+          Ins_SLOOP( exc, args );
           break;
 
         case 0x18:  /* RTG */
-          DO_RTG
+          Ins_RTG( exc );
           break;
 
         case 0x19:  /* RTHG */
-          DO_RTHG
+          Ins_RTHG( exc );
           break;
 
         case 0x1A:  /* SMD */
-          DO_SMD
+          Ins_SMD( exc, args );
           break;
 
         case 0x1B:  /* ELSE */
-          Ins_ELSE( EXEC_ARG_ args );
+          Ins_ELSE( exc );
           break;
 
         case 0x1C:  /* JMPR */
-          DO_JMPR
+          Ins_JMPR( exc, args );
           break;
 
         case 0x1D:  /* SCVTCI */
-          DO_SCVTCI
+          Ins_SCVTCI( exc, args );
           break;
 
         case 0x1E:  /* SSWCI */
-          DO_SSWCI
+          Ins_SSWCI( exc, args );
           break;
 
         case 0x1F:  /* SSW */
-          DO_SSW
+          Ins_SSW( exc, args );
           break;
 
         case 0x20:  /* DUP */
-          DO_DUP
+          Ins_DUP( args );
           break;
 
         case 0x21:  /* POP */
-          /* nothing :-) */
+          Ins_POP();
           break;
 
         case 0x22:  /* CLEAR */
-          DO_CLEAR
+          Ins_CLEAR( exc );
           break;
 
         case 0x23:  /* SWAP */
-          DO_SWAP
+          Ins_SWAP( args );
           break;
 
         case 0x24:  /* DEPTH */
-          DO_DEPTH
+          Ins_DEPTH( exc, args );
           break;
 
         case 0x25:  /* CINDEX */
-          DO_CINDEX
+          Ins_CINDEX( exc, args );
           break;
 
         case 0x26:  /* MINDEX */
-          Ins_MINDEX( EXEC_ARG_ args );
+          Ins_MINDEX( exc, args );
           break;
 
         case 0x27:  /* ALIGNPTS */
-          Ins_ALIGNPTS( EXEC_ARG_ args );
+          Ins_ALIGNPTS( exc, args );
           break;
 
         case 0x28:  /* ???? */
-          Ins_UNKNOWN( EXEC_ARG_ args );
+          Ins_UNKNOWN( exc );
           break;
 
         case 0x29:  /* UTP */
-          Ins_UTP( EXEC_ARG_ args );
+          Ins_UTP( exc, args );
           break;
 
         case 0x2A:  /* LOOPCALL */
-          Ins_LOOPCALL( EXEC_ARG_ args );
+          Ins_LOOPCALL( exc, args );
           break;
 
         case 0x2B:  /* CALL */
-          Ins_CALL( EXEC_ARG_ args );
+          Ins_CALL( exc, args );
           break;
 
         case 0x2C:  /* FDEF */
-          Ins_FDEF( EXEC_ARG_ args );
+          Ins_FDEF( exc, args );
           break;
 
         case 0x2D:  /* ENDF */
-          Ins_ENDF( EXEC_ARG_ args );
+          Ins_ENDF( exc );
           break;
 
         case 0x2E:  /* MDAP */
         case 0x2F:  /* MDAP */
-          Ins_MDAP( EXEC_ARG_ args );
+          Ins_MDAP( exc, args );
           break;
 
         case 0x30:  /* IUP */
         case 0x31:  /* IUP */
-          Ins_IUP( EXEC_ARG_ args );
+          Ins_IUP( exc );
           break;
 
         case 0x32:  /* SHP */
         case 0x33:  /* SHP */
-          Ins_SHP( EXEC_ARG_ args );
+          Ins_SHP( exc );
           break;
 
         case 0x34:  /* SHC */
         case 0x35:  /* SHC */
-          Ins_SHC( EXEC_ARG_ args );
+          Ins_SHC( exc, args );
           break;
 
         case 0x36:  /* SHZ */
         case 0x37:  /* SHZ */
-          Ins_SHZ( EXEC_ARG_ args );
+          Ins_SHZ( exc, args );
           break;
 
         case 0x38:  /* SHPIX */
-          Ins_SHPIX( EXEC_ARG_ args );
+          Ins_SHPIX( exc, args );
           break;
 
         case 0x39:  /* IP    */
-          Ins_IP( EXEC_ARG_ args );
+          Ins_IP( exc );
           break;
 
         case 0x3A:  /* MSIRP */
         case 0x3B:  /* MSIRP */
-          Ins_MSIRP( EXEC_ARG_ args );
+          Ins_MSIRP( exc, args );
           break;
 
         case 0x3C:  /* AlignRP */
-          Ins_ALIGNRP( EXEC_ARG_ args );
+          Ins_ALIGNRP( exc );
           break;
 
         case 0x3D:  /* RTDG */
-          DO_RTDG
+          Ins_RTDG( exc );
           break;
 
         case 0x3E:  /* MIAP */
         case 0x3F:  /* MIAP */
-          Ins_MIAP( EXEC_ARG_ args );
+          Ins_MIAP( exc, args );
           break;
 
         case 0x40:  /* NPUSHB */
-          Ins_NPUSHB( EXEC_ARG_ args );
+          Ins_NPUSHB( exc, args );
           break;
 
         case 0x41:  /* NPUSHW */
-          Ins_NPUSHW( EXEC_ARG_ args );
+          Ins_NPUSHW( exc, args );
           break;
 
         case 0x42:  /* WS */
-          DO_WS
-          break;
-
-      Set_Invalid_Ref:
-            CUR.error = FT_THROW( Invalid_Reference );
+          Ins_WS( exc, args );
           break;
 
         case 0x43:  /* RS */
-          DO_RS
+          Ins_RS( exc, args );
           break;
 
         case 0x44:  /* WCVTP */
-          DO_WCVTP
+          Ins_WCVTP( exc, args );
           break;
 
         case 0x45:  /* RCVT */
-          DO_RCVT
+          Ins_RCVT( exc, args );
           break;
 
         case 0x46:  /* GC */
         case 0x47:  /* GC */
-          Ins_GC( EXEC_ARG_ args );
+          Ins_GC( exc, args );
           break;
 
         case 0x48:  /* SCFS */
-          Ins_SCFS( EXEC_ARG_ args );
+          Ins_SCFS( exc, args );
           break;
 
         case 0x49:  /* MD */
         case 0x4A:  /* MD */
-          Ins_MD( EXEC_ARG_ args );
+          Ins_MD( exc, args );
           break;
 
         case 0x4B:  /* MPPEM */
-          DO_MPPEM
+          Ins_MPPEM( exc, args );
           break;
 
         case 0x4C:  /* MPS */
-          DO_MPS
+          Ins_MPS( exc, args );
           break;
 
         case 0x4D:  /* FLIPON */
-          DO_FLIPON
+          Ins_FLIPON( exc );
           break;
 
         case 0x4E:  /* FLIPOFF */
-          DO_FLIPOFF
+          Ins_FLIPOFF( exc );
           break;
 
         case 0x4F:  /* DEBUG */
-          DO_DEBUG
+          Ins_DEBUG( exc );
           break;
 
         case 0x50:  /* LT */
-          DO_LT
+          Ins_LT( args );
           break;
 
         case 0x51:  /* LTEQ */
-          DO_LTEQ
+          Ins_LTEQ( args );
           break;
 
         case 0x52:  /* GT */
-          DO_GT
+          Ins_GT( args );
           break;
 
         case 0x53:  /* GTEQ */
-          DO_GTEQ
+          Ins_GTEQ( args );
           break;
 
         case 0x54:  /* EQ */
-          DO_EQ
+          Ins_EQ( args );
           break;
 
         case 0x55:  /* NEQ */
-          DO_NEQ
+          Ins_NEQ( args );
           break;
 
         case 0x56:  /* ODD */
-          DO_ODD
+          Ins_ODD( exc, args );
           break;
 
         case 0x57:  /* EVEN */
-          DO_EVEN
+          Ins_EVEN( exc, args );
           break;
 
         case 0x58:  /* IF */
-          Ins_IF( EXEC_ARG_ args );
+          Ins_IF( exc, args );
           break;
 
         case 0x59:  /* EIF */
-          /* do nothing */
+          Ins_EIF();
           break;
 
         case 0x5A:  /* AND */
-          DO_AND
+          Ins_AND( args );
           break;
 
         case 0x5B:  /* OR */
-          DO_OR
+          Ins_OR( args );
           break;
 
         case 0x5C:  /* NOT */
-          DO_NOT
+          Ins_NOT( args );
           break;
 
         case 0x5D:  /* DELTAP1 */
-          Ins_DELTAP( EXEC_ARG_ args );
+          Ins_DELTAP( exc, args );
           break;
 
         case 0x5E:  /* SDB */
-          DO_SDB
+          Ins_SDB( exc, args );
           break;
 
         case 0x5F:  /* SDS */
-          DO_SDS
+          Ins_SDS( exc, args );
           break;
 
         case 0x60:  /* ADD */
-          DO_ADD
+          Ins_ADD( args );
           break;
 
         case 0x61:  /* SUB */
-          DO_SUB
+          Ins_SUB( args );
           break;
 
         case 0x62:  /* DIV */
-          DO_DIV
+          Ins_DIV( exc, args );
           break;
 
         case 0x63:  /* MUL */
-          DO_MUL
+          Ins_MUL( args );
           break;
 
         case 0x64:  /* ABS */
-          DO_ABS
+          Ins_ABS( args );
           break;
 
         case 0x65:  /* NEG */
-          DO_NEG
+          Ins_NEG( args );
           break;
 
         case 0x66:  /* FLOOR */
-          DO_FLOOR
+          Ins_FLOOR( args );
           break;
 
         case 0x67:  /* CEILING */
-          DO_CEILING
+          Ins_CEILING( args );
           break;
 
         case 0x68:  /* ROUND */
         case 0x69:  /* ROUND */
         case 0x6A:  /* ROUND */
         case 0x6B:  /* ROUND */
-          DO_ROUND
+          Ins_ROUND( exc, args );
           break;
 
         case 0x6C:  /* NROUND */
         case 0x6D:  /* NROUND */
         case 0x6E:  /* NRRUND */
         case 0x6F:  /* NROUND */
-          DO_NROUND
+          Ins_NROUND( exc, args );
           break;
 
         case 0x70:  /* WCVTF */
-          DO_WCVTF
+          Ins_WCVTF( exc, args );
           break;
 
         case 0x71:  /* DELTAP2 */
         case 0x72:  /* DELTAP3 */
-          Ins_DELTAP( EXEC_ARG_ args );
+          Ins_DELTAP( exc, args );
           break;
 
         case 0x73:  /* DELTAC0 */
         case 0x74:  /* DELTAC1 */
         case 0x75:  /* DELTAC2 */
-          Ins_DELTAC( EXEC_ARG_ args );
+          Ins_DELTAC( exc, args );
           break;
 
         case 0x76:  /* SROUND */
-          DO_SROUND
+          Ins_SROUND( exc, args );
           break;
 
         case 0x77:  /* S45Round */
-          DO_S45ROUND
+          Ins_S45ROUND( exc, args );
           break;
 
         case 0x78:  /* JROT */
-          DO_JROT
+          Ins_JROT( exc, args );
           break;
 
         case 0x79:  /* JROF */
-          DO_JROF
+          Ins_JROF( exc, args );
           break;
 
         case 0x7A:  /* ROFF */
-          DO_ROFF
+          Ins_ROFF( exc );
           break;
 
         case 0x7B:  /* ???? */
-          Ins_UNKNOWN( EXEC_ARG_ args );
+          Ins_UNKNOWN( exc );
           break;
 
         case 0x7C:  /* RUTG */
-          DO_RUTG
+          Ins_RUTG( exc );
           break;
 
         case 0x7D:  /* RDTG */
-          DO_RDTG
+          Ins_RDTG( exc );
           break;
 
         case 0x7E:  /* SANGW */
-        case 0x7F:  /* AA    */
-          /* nothing - obsolete */
+          Ins_SANGW();
+          break;
+
+        case 0x7F:  /* AA */
+          Ins_AA();
           break;
 
         case 0x80:  /* FLIPPT */
-          Ins_FLIPPT( EXEC_ARG_ args );
+          Ins_FLIPPT( exc );
           break;
 
         case 0x81:  /* FLIPRGON */
-          Ins_FLIPRGON( EXEC_ARG_ args );
+          Ins_FLIPRGON( exc, args );
           break;
 
         case 0x82:  /* FLIPRGOFF */
-          Ins_FLIPRGOFF( EXEC_ARG_ args );
+          Ins_FLIPRGOFF( exc, args );
           break;
 
         case 0x83:  /* UNKNOWN */
         case 0x84:  /* UNKNOWN */
-          Ins_UNKNOWN( EXEC_ARG_ args );
+          Ins_UNKNOWN( exc );
           break;
 
         case 0x85:  /* SCANCTRL */
-          Ins_SCANCTRL( EXEC_ARG_ args );
+          Ins_SCANCTRL( exc, args );
           break;
 
-        case 0x86:  /* SDPVTL */
-        case 0x87:  /* SDPVTL */
-          Ins_SDPVTL( EXEC_ARG_ args );
+        case 0x86:  /* SDPvTL */
+        case 0x87:  /* SDPvTL */
+          Ins_SDPVTL( exc, args );
           break;
 
         case 0x88:  /* GETINFO */
-          Ins_GETINFO( EXEC_ARG_ args );
+          Ins_GETINFO( exc, args );
           break;
 
         case 0x89:  /* IDEF */
-          Ins_IDEF( EXEC_ARG_ args );
+          Ins_IDEF( exc, args );
           break;
 
         case 0x8A:  /* ROLL */
-          Ins_ROLL( EXEC_ARG_ args );
+          Ins_ROLL( args );
           break;
 
         case 0x8B:  /* MAX */
-          DO_MAX
+          Ins_MAX( args );
           break;
 
         case 0x8C:  /* MIN */
-          DO_MIN
+          Ins_MIN( args );
           break;
 
         case 0x8D:  /* SCANTYPE */
-          Ins_SCANTYPE( EXEC_ARG_ args );
+          Ins_SCANTYPE( exc, args );
           break;
 
         case 0x8E:  /* INSTCTRL */
-          Ins_INSTCTRL( EXEC_ARG_ args );
+          Ins_INSTCTRL( exc, args );
           break;
 
         case 0x8F:
-          Ins_UNKNOWN( EXEC_ARG_ args );
+          Ins_UNKNOWN( exc );
           break;
 
         default:
           if ( opcode >= 0xE0 )
-            Ins_MIRP( EXEC_ARG_ args );
+            Ins_MIRP( exc, args );
           else if ( opcode >= 0xC0 )
-            Ins_MDRP( EXEC_ARG_ args );
+            Ins_MDRP( exc, args );
           else if ( opcode >= 0xB8 )
-            Ins_PUSHW( EXEC_ARG_ args );
+            Ins_PUSHW( exc, args );
           else if ( opcode >= 0xB0 )
-            Ins_PUSHB( EXEC_ARG_ args );
+            Ins_PUSHB( exc, args );
           else
-            Ins_UNKNOWN( EXEC_ARG_ args );
+            Ins_UNKNOWN( exc );
         }
-
       }
 
-#else
-
-      Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] );
-
-#endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */
-
-      if ( CUR.error )
+      if ( exc->error )
       {
-        switch ( CUR.error )
+        switch ( exc->error )
         {
           /* looking for redefined instructions */
         case FT_ERR( Invalid_Opcode ):
           {
-            TT_DefRecord*  def   = CUR.IDefs;
-            TT_DefRecord*  limit = def + CUR.numIDefs;
+            TT_DefRecord*  def   = exc->IDefs;
+            TT_DefRecord*  limit = def + exc->numIDefs;
 
 
             for ( ; def < limit; def++ )
             {
-              if ( def->active && CUR.opcode == (FT_Byte)def->opc )
+              if ( def->active && exc->opcode == (FT_Byte)def->opc )
               {
                 TT_CallRec*  callrec;
 
 
-                if ( CUR.callTop >= CUR.callSize )
+                if ( exc->callTop >= exc->callSize )
                 {
-                  CUR.error = FT_THROW( Invalid_Reference );
+                  exc->error = FT_THROW( Invalid_Reference );
                   goto LErrorLabel_;
                 }
 
-                callrec = &CUR.callStack[CUR.callTop];
+                callrec = &exc->callStack[exc->callTop];
 
-                callrec->Caller_Range = CUR.curRange;
-                callrec->Caller_IP    = CUR.IP + 1;
+                callrec->Caller_Range = exc->curRange;
+                callrec->Caller_IP    = exc->IP + 1;
                 callrec->Cur_Count    = 1;
                 callrec->Def          = def;
 
-                if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE )
+                if ( Ins_Goto_CodeRange( exc,
+                                         def->range,
+                                         def->start ) == FAILURE )
                   goto LErrorLabel_;
 
                 goto LSuiteLabel_;
@@ -8974,7 +8215,7 @@
             }
           }
 
-          CUR.error = FT_THROW( Invalid_Opcode );
+          exc->error = FT_THROW( Invalid_Opcode );
           goto LErrorLabel_;
 
 #if 0
@@ -8992,10 +8233,10 @@
         }
       }
 
-      CUR.top = CUR.new_top;
+      exc->top = exc->new_top;
 
-      if ( CUR.step_ins )
-        CUR.IP += CUR.length;
+      if ( exc->step_ins )
+        exc->IP += exc->length;
 
       /* increment instruction counter and check if we didn't */
       /* run this program for too long (e.g. infinite loops). */
@@ -9003,48 +8244,38 @@
         return FT_THROW( Execution_Too_Long );
 
     LSuiteLabel_:
-      if ( CUR.IP >= CUR.codeSize )
+      if ( exc->IP >= exc->codeSize )
       {
-        if ( CUR.callTop > 0 )
+        if ( exc->callTop > 0 )
         {
-          CUR.error = FT_THROW( Code_Overflow );
+          exc->error = FT_THROW( Code_Overflow );
           goto LErrorLabel_;
         }
         else
           goto LNo_Error_;
       }
-    } while ( !CUR.instruction_trap );
+    } while ( !exc->instruction_trap );
 
   LNo_Error_:
-
-#ifdef TT_CONFIG_OPTION_STATIC_RASTER
-    *exc = cur;
-#endif
-
     return FT_Err_Ok;
 
   LErrorCodeOverflow_:
-    CUR.error = FT_THROW( Code_Overflow );
+    exc->error = FT_THROW( Code_Overflow );
 
   LErrorLabel_:
-
-#ifdef TT_CONFIG_OPTION_STATIC_RASTER
-    *exc = cur;
-#endif
-
     /* If any errors have occurred, function tables may be broken. */
     /* Force a re-execution of `prep' and `fpgm' tables if no      */
     /* bytecode debugger is run.                                   */
-    if ( CUR.error
-         && !CUR.instruction_trap
-         && CUR.curRange == tt_coderange_glyph )
+    if ( exc->error                          &&
+         !exc->instruction_trap              &&
+         exc->curRange == tt_coderange_glyph )
     {
-      FT_TRACE1(( "  The interpreter returned error 0x%x\n", CUR.error ));
+      FT_TRACE1(( "  The interpreter returned error 0x%x\n", exc->error ));
       exc->size->bytecode_ready = -1;
       exc->size->cvt_ready      = -1;
     }
 
-    return CUR.error;
+    return exc->error;
   }
 
 
diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h
index 1d8825d..32706d0 100644
--- a/src/truetype/ttinterp.h
+++ b/src/truetype/ttinterp.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType bytecode interpreter (specification).                       */
 /*                                                                         */
-/*  Copyright 1996-2007, 2010, 2012-2013 by                                */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -26,23 +26,6 @@
 FT_BEGIN_HEADER
 
 
-#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */
-
-#define EXEC_OP_   TT_ExecContext  exc,
-#define EXEC_OP    TT_ExecContext  exc
-#define EXEC_ARG_  exc,
-#define EXEC_ARG   exc
-
-#else                                       /* static implementation */
-
-#define EXEC_OP_   /* void */
-#define EXEC_OP    /* void */
-#define EXEC_ARG_  /* void */
-#define EXEC_ARG   /* void */
-
-#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */
-
-
   /*************************************************************************/
   /*                                                                       */
   /* Rounding mode constants.                                              */
@@ -67,29 +50,38 @@
 
   /* Rounding function */
   typedef FT_F26Dot6
-  (*TT_Round_Func)( EXEC_OP_ FT_F26Dot6  distance,
-                             FT_F26Dot6  compensation );
+  (*TT_Round_Func)( TT_ExecContext  exc,
+                    FT_F26Dot6      distance,
+                    FT_F26Dot6      compensation );
 
   /* Point displacement along the freedom vector routine */
   typedef void
-  (*TT_Move_Func)( EXEC_OP_ TT_GlyphZone  zone,
-                            FT_UShort     point,
-                            FT_F26Dot6    distance );
+  (*TT_Move_Func)( TT_ExecContext  exc,
+                   TT_GlyphZone    zone,
+                   FT_UShort       point,
+                   FT_F26Dot6      distance );
 
   /* Distance projection along one of the projection vectors */
   typedef FT_F26Dot6
-  (*TT_Project_Func)( EXEC_OP_ FT_Pos   dx,
-                               FT_Pos   dy );
+  (*TT_Project_Func)( TT_ExecContext  exc,
+                      FT_Pos          dx,
+                      FT_Pos          dy );
+
+  /* getting current ppem.  Take care of non-square pixels if necessary */
+  typedef FT_Long
+  (*TT_Cur_Ppem_Func)( TT_ExecContext  exc );
 
   /* reading a cvt value.  Take care of non-square pixels if necessary */
   typedef FT_F26Dot6
-  (*TT_Get_CVT_Func)( EXEC_OP_ FT_ULong  idx );
+  (*TT_Get_CVT_Func)( TT_ExecContext  exc,
+                      FT_ULong        idx );
 
   /* setting or moving a cvt value.  Take care of non-square pixels  */
   /* if necessary                                                    */
   typedef void
-  (*TT_Set_CVT_Func)( EXEC_OP_ FT_ULong    idx,
-                               FT_F26Dot6  value );
+  (*TT_Set_CVT_Func)( TT_ExecContext  exc,
+                      FT_ULong        idx,
+                      FT_F26Dot6      value );
 
 
   /*************************************************************************/
@@ -166,11 +158,11 @@
 
     FT_Long            top;        /* top of exec. stack   */
 
-    FT_UInt            stackSize;  /* size of exec. stack  */
+    FT_Long            stackSize;  /* size of exec. stack  */
     FT_Long*           stack;      /* current exec. stack  */
 
     FT_Long            args;
-    FT_UInt            new_top;    /* new top after exec.  */
+    FT_Long            new_top;    /* new top after exec.  */
 
     TT_GlyphZoneRec    zp0,        /* zone records */
                        zp1,
@@ -228,11 +220,6 @@
     FT_F26Dot6         phase;      /* `SuperRounding'     */
     FT_F26Dot6         threshold;
 
-#if 0
-    /* this seems to be unused */
-    FT_Int             cur_ppem;   /* ppem along the current proj vector */
-#endif
-
     FT_Bool            instruction_trap; /* If `True', the interpreter will */
                                          /* exit after each instruction     */
 
@@ -254,6 +241,8 @@
     TT_Move_Func       func_move;      /* current point move function */
     TT_Move_Func       func_move_orig; /* move original position function */
 
+    TT_Cur_Ppem_Func   func_cur_ppem;  /* get current proj. ppem value  */
+
     TT_Get_CVT_Func    func_read_cvt;  /* read a cvt entry              */
     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)  */
@@ -263,18 +252,22 @@
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     TT_Round_Func      func_round_sphn;   /* subpixel rounding function */
 
-    FT_Bool            subpixel;          /* Using subpixel hinting?       */
+    FT_Bool            subpixel_hinting;  /* Using subpixel hinting?       */
     FT_Bool            ignore_x_mode;     /* Standard rendering mode for   */
                                           /* subpixel hinting.  On if gray */
                                           /* or subpixel hinting is on.    */
 
-    /* The following 4 aren't fully implemented but here for MS rasterizer */
+    /* The following 6 aren't fully implemented but here for MS rasterizer */
     /* compatibility.                                                      */
     FT_Bool            compatible_widths;     /* compatible widths?        */
     FT_Bool            symmetrical_smoothing; /* symmetrical_smoothing?    */
     FT_Bool            bgr;                   /* bgr instead of rgb?       */
+    FT_Bool            vertical_lcd;          /* long side of LCD subpixel */
+                                              /* rectangles is horizontal  */
     FT_Bool            subpixel_positioned;   /* subpixel positioned       */
                                               /* (DirectWrite ClearType)?  */
+    FT_Bool            gray_cleartype;        /* ClearType hinting but     */
+                                              /* grayscale rendering       */
 
     FT_Int             rasterizer_version;    /* MS rasterizer version     */
 
@@ -295,18 +288,18 @@
 
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
-  FT_LOCAL( FT_Error )
+  FT_LOCAL( void )
   TT_Goto_CodeRange( TT_ExecContext  exec,
                      FT_Int          range,
                      FT_Long         IP );
 
-  FT_LOCAL( FT_Error )
+  FT_LOCAL( void )
   TT_Set_CodeRange( TT_ExecContext  exec,
                     FT_Int          range,
                     void*           base,
                     FT_Long         length );
 
-  FT_LOCAL( FT_Error )
+  FT_LOCAL( void )
   TT_Clear_CodeRange( TT_ExecContext  exec,
                       FT_Int          range );
 
@@ -314,7 +307,7 @@
   FT_LOCAL( FT_Error )
   Update_Max( FT_Memory  memory,
               FT_ULong*  size,
-              FT_Long    multiplier,
+              FT_ULong   multiplier,
               void*      _pbuff,
               FT_ULong   new_max );
 #endif /* TT_USE_BYTECODE_INTERPRETER */
@@ -338,13 +331,14 @@
   /*                                                                       */
   /* <Note>                                                                */
   /*    Only the glyph loader and debugger should call this function.      */
+  /*    (And right now only the glyph loader uses it.)                     */
   /*                                                                       */
   FT_EXPORT( TT_ExecContext )
   TT_New_Context( TT_Driver  driver );
 
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
-  FT_LOCAL( FT_Error )
+  FT_LOCAL( void )
   TT_Done_Context( TT_ExecContext  exec );
 
   FT_LOCAL( FT_Error )
@@ -352,13 +346,12 @@
                    TT_Face         face,
                    TT_Size         size );
 
-  FT_LOCAL( FT_Error )
+  FT_LOCAL( void )
   TT_Save_Context( TT_ExecContext  exec,
                    TT_Size         ins );
 
   FT_LOCAL( FT_Error )
-  TT_Run_Context( TT_ExecContext  exec,
-                  FT_Bool         debug );
+  TT_Run_Context( TT_ExecContext  exec );
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
 
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index 05a121c..202aa04 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Objects manager (body).                                              */
 /*                                                                         */
-/*  Copyright 1996-2013                                                    */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -256,89 +256,89 @@
 #define TRICK_SFNT_ID_prep  2
 
       { /* MingLiU 1995 */
-        { 0x05bcf058, 0x000002e4 }, /* cvt  */
-        { 0x28233bf1, 0x000087c4 }, /* fpgm */
-        { 0xa344a1ea, 0x000001e1 }  /* prep */
+        { 0x05BCF058UL, 0x000002E4UL }, /* cvt  */
+        { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */
+        { 0xA344A1EAUL, 0x000001E1UL }  /* prep */
       },
       { /* MingLiU 1996- */
-        { 0x05bcf058, 0x000002e4 }, /* cvt  */
-        { 0x28233bf1, 0x000087c4 }, /* fpgm */
-        { 0xa344a1eb, 0x000001e1 }  /* prep */
+        { 0x05BCF058UL, 0x000002E4UL }, /* cvt  */
+        { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */
+        { 0xA344A1EBUL, 0x000001E1UL }  /* prep */
       },
       { /* DFKaiShu */
-        { 0x11e5ead4, 0x00000350 }, /* cvt  */
-        { 0x5a30ca3b, 0x00009063 }, /* fpgm */
-        { 0x13a42602, 0x0000007e }  /* prep */
+        { 0x11E5EAD4UL, 0x00000350UL }, /* cvt  */
+        { 0x5A30CA3BUL, 0x00009063UL }, /* fpgm */
+        { 0x13A42602UL, 0x0000007EUL }  /* prep */
       },
       { /* HuaTianKaiTi */
-        { 0xfffbfffc, 0x00000008 }, /* cvt  */
-        { 0x9c9e48b8, 0x0000bea2 }, /* fpgm */
-        { 0x70020112, 0x00000008 }  /* prep */
+        { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt  */
+        { 0x9C9E48B8UL, 0x0000BEA2UL }, /* fpgm */
+        { 0x70020112UL, 0x00000008UL }  /* prep */
       },
       { /* HuaTianSongTi */
-        { 0xfffbfffc, 0x00000008 }, /* cvt  */
-        { 0x0a5a0483, 0x00017c39 }, /* fpgm */
-        { 0x70020112, 0x00000008 }  /* prep */
+        { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt  */
+        { 0x0A5A0483UL, 0x00017C39UL }, /* fpgm */
+        { 0x70020112UL, 0x00000008UL }  /* prep */
       },
       { /* NEC fadpop7.ttf */
-        { 0x00000000, 0x00000000 }, /* cvt  */
-        { 0x40c92555, 0x000000e5 }, /* fpgm */
-        { 0xa39b58e3, 0x0000117c }  /* prep */
+        { 0x00000000UL, 0x00000000UL }, /* cvt  */
+        { 0x40C92555UL, 0x000000E5UL }, /* fpgm */
+        { 0xA39B58E3UL, 0x0000117CUL }  /* prep */
       },
       { /* NEC fadrei5.ttf */
-        { 0x00000000, 0x00000000 }, /* cvt  */
-        { 0x33c41652, 0x000000e5 }, /* fpgm */
-        { 0x26d6c52a, 0x00000f6a }  /* prep */
+        { 0x00000000UL, 0x00000000UL }, /* cvt  */
+        { 0x33C41652UL, 0x000000E5UL }, /* fpgm */
+        { 0x26D6C52AUL, 0x00000F6AUL }  /* prep */
       },
       { /* NEC fangot7.ttf */
-        { 0x00000000, 0x00000000 }, /* cvt  */
-        { 0x6db1651d, 0x0000019d }, /* fpgm */
-        { 0x6c6e4b03, 0x00002492 }  /* prep */
+        { 0x00000000UL, 0x00000000UL }, /* cvt  */
+        { 0x6DB1651DUL, 0x0000019DUL }, /* fpgm */
+        { 0x6C6E4B03UL, 0x00002492UL }  /* prep */
       },
       { /* NEC fangyo5.ttf */
-        { 0x00000000, 0x00000000 }, /* cvt  */
-        { 0x40c92555, 0x000000e5 }, /* fpgm */
-        { 0xde51fad0, 0x0000117c }  /* prep */
+        { 0x00000000UL, 0x00000000UL }, /* cvt  */
+        { 0x40C92555UL, 0x000000E5UL }, /* fpgm */
+        { 0xDE51FAD0UL, 0x0000117CUL }  /* prep */
       },
       { /* NEC fankyo5.ttf */
-        { 0x00000000, 0x00000000 }, /* cvt  */
-        { 0x85e47664, 0x000000e5 }, /* fpgm */
-        { 0xa6c62831, 0x00001caa }  /* prep */
+        { 0x00000000UL, 0x00000000UL }, /* cvt  */
+        { 0x85E47664UL, 0x000000E5UL }, /* fpgm */
+        { 0xA6C62831UL, 0x00001CAAUL }  /* prep */
       },
       { /* NEC fanrgo5.ttf */
-        { 0x00000000, 0x00000000 }, /* cvt  */
-        { 0x2d891cfd, 0x0000019d }, /* fpgm */
-        { 0xa0604633, 0x00001de8 }  /* prep */
+        { 0x00000000UL, 0x00000000UL }, /* cvt  */
+        { 0x2D891CFDUL, 0x0000019DUL }, /* fpgm */
+        { 0xA0604633UL, 0x00001DE8UL }  /* prep */
       },
       { /* NEC fangot5.ttc */
-        { 0x00000000, 0x00000000 }, /* cvt  */
-        { 0x40aa774c, 0x000001cb }, /* fpgm */
-        { 0x9b5caa96, 0x00001f9a }  /* prep */
+        { 0x00000000UL, 0x00000000UL }, /* cvt  */
+        { 0x40AA774CUL, 0x000001CBUL }, /* fpgm */
+        { 0x9B5CAA96UL, 0x00001F9AUL }  /* prep */
       },
       { /* NEC fanmin3.ttc */
-        { 0x00000000, 0x00000000 }, /* cvt  */
-        { 0x0d3de9cb, 0x00000141 }, /* fpgm */
-        { 0xd4127766, 0x00002280 }  /* prep */
+        { 0x00000000UL, 0x00000000UL }, /* cvt  */
+        { 0x0D3DE9CBUL, 0x00000141UL }, /* fpgm */
+        { 0xD4127766UL, 0x00002280UL }  /* prep */
       },
       { /* NEC FA-Gothic, 1996 */
-        { 0x00000000, 0x00000000 }, /* cvt  */
-        { 0x4a692698, 0x000001f0 }, /* fpgm */
-        { 0x340d4346, 0x00001fca }  /* prep */
+        { 0x00000000UL, 0x00000000UL }, /* cvt  */
+        { 0x4A692698UL, 0x000001F0UL }, /* fpgm */
+        { 0x340D4346UL, 0x00001FCAUL }  /* prep */
       },
       { /* NEC FA-Minchou, 1996 */
-        { 0x00000000, 0x00000000 }, /* cvt  */
-        { 0xcd34c604, 0x00000166 }, /* fpgm */
-        { 0x6cf31046, 0x000022b0 }  /* prep */
+        { 0x00000000UL, 0x00000000UL }, /* cvt  */
+        { 0xCD34C604UL, 0x00000166UL }, /* fpgm */
+        { 0x6CF31046UL, 0x000022B0UL }  /* prep */
       },
       { /* NEC FA-RoundGothicB, 1996 */
-        { 0x00000000, 0x00000000 }, /* cvt  */
-        { 0x5da75315, 0x0000019d }, /* fpgm */
-        { 0x40745a5f, 0x000022e0 }  /* prep */
+        { 0x00000000UL, 0x00000000UL }, /* cvt  */
+        { 0x5DA75315UL, 0x0000019DUL }, /* fpgm */
+        { 0x40745A5FUL, 0x000022E0UL }  /* prep */
       },
       { /* NEC FA-RoundGothicM, 1996 */
-        { 0x00000000, 0x00000000 }, /* cvt  */
-        { 0xf055fc48, 0x000001c2 }, /* fpgm */
-        { 0x3900ded3, 0x00001e18 }  /* prep */
+        { 0x00000000UL, 0x00000000UL }, /* cvt  */
+        { 0xF055FC48UL, 0x000001C2UL }, /* fpgm */
+        { 0x3900DED3UL, 0x00001E18UL }  /* prep */
       }
     };
 
@@ -751,16 +751,11 @@
     FT_Error        error;
 
 
-    /* debugging instances have their own context */
-    if ( size->debug )
-      exec = size->context;
-    else
-      exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
+    exec = size->context;
 
-    if ( !exec )
-      return FT_THROW( Could_Not_Find_Context );
-
-    TT_Load_Context( exec, face, size );
+    error = TT_Load_Context( exec, face, size );
+    if ( error )
+      return error;
 
     exec->callTop = 0;
     exec->top     = 0;
@@ -793,7 +788,7 @@
     TT_Set_CodeRange( exec,
                       tt_coderange_font,
                       face->font_program,
-                      face->font_program_size );
+                      (FT_Long)face->font_program_size );
 
     /* disable CVT and glyph programs coderange */
     TT_Clear_CodeRange( exec, tt_coderange_cvt );
@@ -801,14 +796,10 @@
 
     if ( face->font_program_size > 0 )
     {
-      error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
+      TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
 
-      if ( !error )
-      {
-        FT_TRACE4(( "Executing `fpgm' table.\n" ));
-
-        error = face->interpreter( exec );
-      }
+      FT_TRACE4(( "Executing `fpgm' table.\n" ));
+      error = face->interpreter( exec );
     }
     else
       error = FT_Err_Ok;
@@ -847,16 +838,11 @@
     FT_Error        error;
 
 
-    /* debugging instances have their own context */
-    if ( size->debug )
-      exec = size->context;
-    else
-      exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
+    exec = size->context;
 
-    if ( !exec )
-      return FT_THROW( Could_Not_Find_Context );
-
-    TT_Load_Context( exec, face, size );
+    error = TT_Load_Context( exec, face, size );
+    if ( error )
+      return error;
 
     exec->callTop = 0;
     exec->top     = 0;
@@ -868,20 +854,17 @@
     TT_Set_CodeRange( exec,
                       tt_coderange_cvt,
                       face->cvt_program,
-                      face->cvt_program_size );
+                      (FT_Long)face->cvt_program_size );
 
     TT_Clear_CodeRange( exec, tt_coderange_glyph );
 
     if ( face->cvt_program_size > 0 )
     {
-      error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
+      TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
 
-      if ( !error && !size->debug )
-      {
-        FT_TRACE4(( "Executing `prep' table.\n" ));
+      FT_TRACE4(( "Executing `prep' table.\n" ));
 
-        error = face->interpreter( exec );
-      }
+      error = face->interpreter( exec );
     }
     else
       error = FT_Err_Ok;
@@ -924,12 +907,10 @@
     TT_Face    face   = (TT_Face)ftsize->face;
     FT_Memory  memory = face->root.memory;
 
-
-    if ( size->debug )
+    if ( size->context )
     {
-      /* the debug context must be deleted by the debugger itself */
+      TT_Done_Context( size->context );
       size->context = NULL;
-      size->debug   = FALSE;
     }
 
     FT_FREE( size->cvt );
@@ -968,15 +949,26 @@
     TT_Size    size = (TT_Size)ftsize;
     TT_Face    face = (TT_Face)ftsize->face;
     FT_Memory  memory = face->root.memory;
-    FT_Int     i;
 
     FT_UShort       n_twilight;
     TT_MaxProfile*  maxp = &face->max_profile;
 
 
+    /* clean up bytecode related data */
+    FT_FREE( size->function_defs );
+    FT_FREE( size->instruction_defs );
+    FT_FREE( size->cvt );
+    FT_FREE( size->storage );
+
+    if ( size->context )
+      TT_Done_Context( size->context );
+    tt_glyphzone_done( &size->twilight );
+
     size->bytecode_ready = -1;
     size->cvt_ready      = -1;
 
+    size->context = TT_New_Context( (TT_Driver)face->root.driver );
+
     size->max_function_defs    = maxp->maxFunctionDefs;
     size->max_instruction_defs = maxp->maxInstructionDefs;
 
@@ -997,9 +989,11 @@
       metrics->rotated   = FALSE;
       metrics->stretched = FALSE;
 
-      /* set default compensation (all 0) */
-      for ( i = 0; i < 4; i++ )
-        metrics->compensations[i] = 0;
+      /* set default engine compensation */
+      metrics->compensations[0] = 0;   /* gray     */
+      metrics->compensations[1] = 0;   /* black    */
+      metrics->compensations[2] = 0;   /* white    */
+      metrics->compensations[3] = 0;   /* reserved */
     }
 
     /* allocate function defs, instruction defs, cvt, and storage area */
@@ -1115,6 +1109,7 @@
     TT_Size   size  = (TT_Size)ttsize;
     FT_Error  error = FT_Err_Ok;
 
+
 #ifdef TT_USE_BYTECODE_INTERPRETER
     size->bytecode_ready = -1;
     size->cvt_ready      = -1;
@@ -1145,8 +1140,7 @@
 
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
-    if ( size->bytecode_ready >= 0 )
-      tt_size_done_bytecode( ttsize );
+    tt_size_done_bytecode( ttsize );
 #endif
 
     size->ttmetrics.valid = FALSE;
@@ -1258,10 +1252,6 @@
 
     TT_Driver  driver = (TT_Driver)ttdriver;
 
-
-    if ( !TT_New_Context( driver ) )
-      return FT_THROW( Could_Not_Find_Context );
-
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
     driver->interpreter_version = TT_INTERPRETER_VERSION_38;
 #else
@@ -1292,20 +1282,7 @@
   FT_LOCAL_DEF( void )
   tt_driver_done( FT_Module  ttdriver )     /* TT_Driver */
   {
-#ifdef TT_USE_BYTECODE_INTERPRETER
-    TT_Driver  driver = (TT_Driver)ttdriver;
-
-
-    /* destroy the execution context */
-    if ( driver->context )
-    {
-      TT_Done_Context( driver->context );
-      driver->context = NULL;
-    }
-#else
     FT_UNUSED( ttdriver );
-#endif
-
   }
 
 
diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h
index 47d50d9..7ac4123 100644
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Objects manager (specification).                                     */
 /*                                                                         */
-/*  Copyright 1996-2009, 2011-2014 by                                      */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -95,8 +95,8 @@
     FT_F26Dot6     control_value_cutin;
     FT_F26Dot6     single_width_cutin;
     FT_F26Dot6     single_width_value;
-    FT_Short       delta_base;
-    FT_Short       delta_shift;
+    FT_UShort      delta_base;
+    FT_UShort      delta_shift;
 
     FT_Byte        instruct_control;
     /* According to Greg Hitchcock from Microsoft, the `scan_control'     */
@@ -160,7 +160,7 @@
   typedef struct  TT_CodeRange_
   {
     FT_Byte*  base;
-    FT_ULong  size;
+    FT_Long   size;
 
   } TT_CodeRange;
 
@@ -324,13 +324,6 @@
 
     TT_GlyphZoneRec    twilight;     /* The instance's twilight zone    */
 
-    /* debugging variables */
-
-    /* When using the debugger, we must keep the */
-    /* execution context tied to the instance    */
-    /* object rather than asking it on demand.   */
-
-    FT_Bool            debug;
     TT_ExecContext     context;
 
     /* if negative, `fpgm' (resp. `prep'), wasn't executed yet; */
@@ -351,7 +344,6 @@
   {
     FT_DriverRec  root;
 
-    TT_ExecContext   context;  /* execution context        */
     TT_GlyphZoneRec  zone;     /* glyph loader points zone */
 
     FT_UInt  interpreter_version;
diff --git a/src/truetype/ttpic.c b/src/truetype/ttpic.c
index edefae7..242a6b7 100644
--- a/src/truetype/ttpic.c
+++ b/src/truetype/ttpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for truetype module. */
 /*                                                                         */
-/*  Copyright 2009, 2010, 2012, 2013 by                                    */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/ttpic.h b/src/truetype/ttpic.h
index cfb4ee6..48ba4aa 100644
--- a/src/truetype/ttpic.h
+++ b/src/truetype/ttpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for truetype module. */
 /*                                                                         */
-/*  Copyright 2009, 2012, 2013 by                                          */
+/*  Copyright 2009-2015 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c
index 9723a51..fb338bd 100644
--- a/src/truetype/ttpload.c
+++ b/src/truetype/ttpload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType-specific tables loader (body).                              */
 /*                                                                         */
-/*  Copyright 1996-2002, 2004-2013 by                                      */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -118,20 +118,20 @@
       /* we only handle the case where `maxp' gives a larger value */
       if ( face->num_locations <= (FT_ULong)face->root.num_glyphs )
       {
-        FT_Long   new_loca_len =
-                    ( (FT_Long)( face->root.num_glyphs ) + 1 ) << shift;
+        FT_ULong  new_loca_len =
+                    ( (FT_ULong)face->root.num_glyphs + 1 ) << shift;
 
         TT_Table  entry = face->dir_tables;
         TT_Table  limit = entry + face->num_tables;
 
-        FT_Long   pos  = FT_Stream_Pos( stream );
+        FT_Long   pos  = (FT_Long)FT_STREAM_POS();
         FT_Long   dist = 0x7FFFFFFFL;
 
 
         /* compute the distance to next table in font file */
         for ( ; entry < limit; entry++ )
         {
-          FT_Long  diff = entry->Offset - pos;
+          FT_Long  diff = (FT_Long)entry->Offset - pos;
 
 
           if ( diff > 0 && diff < dist )
@@ -141,12 +141,12 @@
         if ( entry == limit )
         {
           /* `loca' is the last table */
-          dist = stream->size - pos;
+          dist = (FT_Long)stream->size - pos;
         }
 
-        if ( new_loca_len <= dist )
+        if ( new_loca_len <= (FT_ULong)dist )
         {
-          face->num_locations = face->root.num_glyphs + 1;
+          face->num_locations = (FT_ULong)face->root.num_glyphs + 1;
           table_len           = new_loca_len;
 
           FT_TRACE2(( "adjusting num_locations to %d\n",
@@ -508,9 +508,9 @@
     record_size = FT_NEXT_ULONG( p );
 
     /* The maximum number of bytes in an hdmx device record is the */
-    /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is   */
-    /* the reason why `record_size' is a long (which we read as    */
-    /* unsigned long for convenience).  In practice, two bytes     */
+    /* maximum number of glyphs + 2; this is 0xFFFF + 2, thus      */
+    /* explaining why `record_size' is a long (which we read as    */
+    /* unsigned long for convenience).  In practice, two bytes are */
     /* sufficient to hold the size value.                          */
     /*                                                             */
     /* There are at least two fonts, HANNOM-A and HANNOM-B version */
@@ -522,8 +522,10 @@
       record_size &= 0xFFFFU;
 
     /* The limit for `num_records' is a heuristic value. */
-
-    if ( version != 0 || num_records > 255 || record_size > 0x10001L )
+    if ( version != 0           ||
+         num_records > 255      ||
+         record_size > 0x10001L ||
+         record_size < 4        )
     {
       error = FT_THROW( Invalid_File_Format );
       goto Fail;
diff --git a/src/truetype/ttpload.h b/src/truetype/ttpload.h
index f61ac07..bc92369 100644
--- a/src/truetype/ttpload.h
+++ b/src/truetype/ttpload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType-specific tables loader (specification).                     */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2005, 2006 by                               */
+/*  Copyright 1996-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/ttsubpix.c b/src/truetype/ttsubpix.c
index 9871994..dbda4d9 100644
--- a/src/truetype/ttsubpix.c
+++ b/src/truetype/ttsubpix.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType Subpixel Hinting.                                           */
 /*                                                                         */
-/*  Copyright 2010-2013 by                                                 */
+/*  Copyright 2010-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -63,8 +63,8 @@
   /* rules below.  A blank entry "" is required at the end of these!       */
 #define FAMILY_CLASS_RULES_SIZE  7
 
-  static const SPH_Font_Class FAMILY_CLASS_Rules
-                              [FAMILY_CLASS_RULES_SIZE] =
+  static const SPH_Font_Class  FAMILY_CLASS_Rules
+                               [FAMILY_CLASS_RULES_SIZE] =
   {
     { "MS Legacy Fonts",
       { "Aharoni",
@@ -223,8 +223,8 @@
   /* rules below.  A blank entry "" is required at the end of these!       */
 #define STYLE_CLASS_RULES_SIZE  5
 
-  const SPH_Font_Class STYLE_CLASS_Rules
-                       [STYLE_CLASS_RULES_SIZE] =
+  static const SPH_Font_Class  STYLE_CLASS_Rules
+                               [STYLE_CLASS_RULES_SIZE] =
   {
     { "Regular Class",
       { "Regular",
@@ -279,18 +279,18 @@
   /* Force special legacy fixes for fonts.                                 */
 #define COMPATIBILITY_MODE_RULES_SIZE  1
 
-  const SPH_TweakRule  COMPATIBILITY_MODE_Rules
-                       [COMPATIBILITY_MODE_RULES_SIZE] =
+  static const SPH_TweakRule  COMPATIBILITY_MODE_Rules
+                              [COMPATIBILITY_MODE_RULES_SIZE] =
   {
-    { "-", 0, "", 0 },
+    { "Verdana Clones", 0, "", 0 },
   };
 
 
   /* Don't do subpixel (ignore_x_mode) hinting; do normal hinting.         */
 #define PIXEL_HINTING_RULES_SIZE  2
 
-  const SPH_TweakRule  PIXEL_HINTING_Rules
-                       [PIXEL_HINTING_RULES_SIZE] =
+  static const SPH_TweakRule  PIXEL_HINTING_Rules
+                              [PIXEL_HINTING_RULES_SIZE] =
   {
     /* these characters are almost always safe */
     { "Courier New", 12, "Italic", 'z' },
@@ -301,8 +301,8 @@
   /* Subpixel hinting ignores SHPIX rules on X.  Force SHPIX for these.    */
 #define DO_SHPIX_RULES_SIZE  1
 
-  const SPH_TweakRule  DO_SHPIX_Rules
-                       [DO_SHPIX_RULES_SIZE] =
+  static const SPH_TweakRule  DO_SHPIX_Rules
+                              [DO_SHPIX_RULES_SIZE] =
   {
     { "-", 0, "", 0 },
   };
@@ -312,8 +312,8 @@
   /* boundary and don't move that point to a Y pixel boundary.             */
 #define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE  4
 
-  const SPH_TweakRule  SKIP_NONPIXEL_Y_MOVES_Rules
-                       [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] =
+  static const SPH_TweakRule  SKIP_NONPIXEL_Y_MOVES_Rules
+                              [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] =
   {
     /* fix vwxyz thinness*/
     { "Consolas", 0, "", 0 },
@@ -328,8 +328,8 @@
 
 #define SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE  1
 
-  const SPH_TweakRule  SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions
-                       [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
+  static const SPH_TweakRule  SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions
+                              [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
   {
     /* Fixes < and > */
     { "Courier New", 0, "Regular", 0 },
@@ -340,8 +340,8 @@
   /* boundary and don't move that point to a Y pixel boundary.             */
 #define SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE  2
 
-  const SPH_TweakRule  SKIP_NONPIXEL_Y_MOVES_DELTAP_Rules
-                       [SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE] =
+  static const SPH_TweakRule  SKIP_NONPIXEL_Y_MOVES_DELTAP_Rules
+                              [SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE] =
   {
     /* Maintain thickness of diagonal in 'N' */
     { "Times New Roman", 0, "Regular/Bold Class", 'N' },
@@ -352,8 +352,8 @@
   /* Skip Y moves that move a point off a Y pixel boundary.                */
 #define SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE  1
 
-  const SPH_TweakRule  SKIP_OFFPIXEL_Y_MOVES_Rules
-                       [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] =
+  static const SPH_TweakRule  SKIP_OFFPIXEL_Y_MOVES_Rules
+                              [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] =
   {
     { "-", 0, "", 0 },
   };
@@ -361,8 +361,8 @@
 
 #define SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE  1
 
-  const SPH_TweakRule  SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions
-                       [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
+  static const SPH_TweakRule  SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions
+                              [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
   {
     { "-", 0, "", 0 },
   };
@@ -371,8 +371,8 @@
   /* Round moves that don't move a point to a Y pixel boundary.            */
 #define ROUND_NONPIXEL_Y_MOVES_RULES_SIZE  2
 
-  const SPH_TweakRule  ROUND_NONPIXEL_Y_MOVES_Rules
-                       [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] =
+  static const SPH_TweakRule  ROUND_NONPIXEL_Y_MOVES_Rules
+                              [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] =
   {
     /* Droid font instructions don't snap Y to pixels */
     { "Droid Sans", 0, "Regular/Italic Class", 0 },
@@ -382,8 +382,8 @@
 
 #define ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE  1
 
-  const SPH_TweakRule  ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions
-                       [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
+  static const SPH_TweakRule  ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions
+                              [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
   {
     { "-", 0, "", 0 },
   };
@@ -392,8 +392,8 @@
   /* Allow a Direct_Move along X freedom vector if matched.                */
 #define ALLOW_X_DMOVE_RULES_SIZE  1
 
-  const SPH_TweakRule  ALLOW_X_DMOVE_Rules
-                       [ALLOW_X_DMOVE_RULES_SIZE] =
+  static const SPH_TweakRule  ALLOW_X_DMOVE_Rules
+                              [ALLOW_X_DMOVE_RULES_SIZE] =
   {
     /* Fixes vanishing diagonal in 4 */
     { "Verdana", 0, "Regular", '4' },
@@ -403,8 +403,8 @@
   /* Return MS rasterizer version 35 if matched.                           */
 #define RASTERIZER_35_RULES_SIZE  8
 
-  const SPH_TweakRule  RASTERIZER_35_Rules
-                       [RASTERIZER_35_RULES_SIZE] =
+  static const SPH_TweakRule  RASTERIZER_35_Rules
+                              [RASTERIZER_35_RULES_SIZE] =
   {
     /* This seems to be the only way to make these look good */
     { "Times New Roman", 0, "Regular", 'i' },
@@ -421,8 +421,8 @@
   /* Don't round to the subpixel grid.  Round to pixel grid.               */
 #define NORMAL_ROUND_RULES_SIZE  1
 
-  const SPH_TweakRule  NORMAL_ROUND_Rules
-                       [NORMAL_ROUND_RULES_SIZE] =
+  static const SPH_TweakRule  NORMAL_ROUND_Rules
+                              [NORMAL_ROUND_RULES_SIZE] =
   {
     /* Fix serif thickness for certain ppems */
     /* Can probably be generalized somehow   */
@@ -433,8 +433,8 @@
   /* Skip IUP instructions if matched.                                     */
 #define SKIP_IUP_RULES_SIZE  1
 
-  const SPH_TweakRule  SKIP_IUP_Rules
-                       [SKIP_IUP_RULES_SIZE] =
+  static const SPH_TweakRule  SKIP_IUP_Rules
+                              [SKIP_IUP_RULES_SIZE] =
   {
     { "Arial", 13, "Regular", 'a' },
   };
@@ -443,8 +443,8 @@
   /* Skip MIAP Twilight hack if matched.                                   */
 #define MIAP_HACK_RULES_SIZE  1
 
-  const SPH_TweakRule  MIAP_HACK_Rules
-                       [MIAP_HACK_RULES_SIZE] =
+  static const SPH_TweakRule  MIAP_HACK_Rules
+                              [MIAP_HACK_RULES_SIZE] =
   {
     { "Geneva", 12, "", 0 },
   };
@@ -453,8 +453,8 @@
   /* Skip DELTAP instructions if matched.                                  */
 #define ALWAYS_SKIP_DELTAP_RULES_SIZE  23
 
-  const SPH_TweakRule  ALWAYS_SKIP_DELTAP_Rules
-                       [ALWAYS_SKIP_DELTAP_RULES_SIZE] =
+  static const SPH_TweakRule  ALWAYS_SKIP_DELTAP_Rules
+                              [ALWAYS_SKIP_DELTAP_RULES_SIZE] =
   {
     { "Georgia", 0, "Regular", 'k' },
     /* fix various problems with e in different versions */
@@ -489,8 +489,8 @@
   /* Always do DELTAP instructions if matched.                             */
 #define ALWAYS_DO_DELTAP_RULES_SIZE  1
 
-  const SPH_TweakRule  ALWAYS_DO_DELTAP_Rules
-                       [ALWAYS_DO_DELTAP_RULES_SIZE] =
+  static const SPH_TweakRule  ALWAYS_DO_DELTAP_Rules
+                              [ALWAYS_DO_DELTAP_RULES_SIZE] =
   {
     { "-", 0, "", 0 },
   };
@@ -744,7 +744,7 @@
 #endif /* FORCE_NATURAL_WIDTHS */
 
 
-  FT_LOCAL_DEF( FT_Bool )
+  static FT_Bool
   is_member_of_family_class( const FT_String*  detected_font_name,
                              const FT_String*  rule_font_name )
   {
@@ -779,7 +779,7 @@
   }
 
 
-  FT_LOCAL_DEF( FT_Bool )
+  static FT_Bool
   is_member_of_style_class( const FT_String*  detected_font_style,
                             const FT_String*  rule_font_style )
   {
@@ -905,7 +905,7 @@
   {
     TT_Face     face   = (TT_Face)loader->face;
     FT_String*  family = face->root.family_name;
-    int         ppem   = loader->size->metrics.x_ppem;
+    FT_UInt     ppem   = loader->size->metrics.x_ppem;
     FT_String*  style  = face->root.style_name;
 
 
diff --git a/src/truetype/ttsubpix.h b/src/truetype/ttsubpix.h
index 8a54fc7..9151aa3 100644
--- a/src/truetype/ttsubpix.h
+++ b/src/truetype/ttsubpix.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType Subpixel Hinting.                                           */
 /*                                                                         */
-/*  Copyright 2010-2013 by                                                 */
+/*  Copyright 2010-2015 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -50,26 +50,26 @@
   /* Tweak flags that are set for each glyph by the below rules.           */
   /*                                                                       */
   /*                                                                       */
-#define SPH_TWEAK_ALLOW_X_DMOVE                   0x0000001
-#define SPH_TWEAK_ALWAYS_DO_DELTAP                0x0000002
-#define SPH_TWEAK_ALWAYS_SKIP_DELTAP              0x0000004
-#define SPH_TWEAK_COURIER_NEW_2_HACK              0x0000008
-#define SPH_TWEAK_DEEMBOLDEN                      0x0000010
-#define SPH_TWEAK_DO_SHPIX                        0x0000020
-#define SPH_TWEAK_EMBOLDEN                        0x0000040
-#define SPH_TWEAK_MIAP_HACK                       0x0000080
-#define SPH_TWEAK_NORMAL_ROUND                    0x0000100
-#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP            0x0000200
-#define SPH_TWEAK_NO_CALL_AFTER_IUP               0x0000400
-#define SPH_TWEAK_NO_DELTAP_AFTER_IUP             0x0000800
-#define SPH_TWEAK_PIXEL_HINTING                   0x0001000
-#define SPH_TWEAK_RASTERIZER_35                   0x0002000
-#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES          0x0004000
-#define SPH_TWEAK_SKIP_IUP                        0x0008000
-#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES           0x0010000
-#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES           0x0020000
-#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK            0x0040000
-#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP    0x0080000
+#define SPH_TWEAK_ALLOW_X_DMOVE                   0x0000001UL
+#define SPH_TWEAK_ALWAYS_DO_DELTAP                0x0000002UL
+#define SPH_TWEAK_ALWAYS_SKIP_DELTAP              0x0000004UL
+#define SPH_TWEAK_COURIER_NEW_2_HACK              0x0000008UL
+#define SPH_TWEAK_DEEMBOLDEN                      0x0000010UL
+#define SPH_TWEAK_DO_SHPIX                        0x0000020UL
+#define SPH_TWEAK_EMBOLDEN                        0x0000040UL
+#define SPH_TWEAK_MIAP_HACK                       0x0000080UL
+#define SPH_TWEAK_NORMAL_ROUND                    0x0000100UL
+#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP            0x0000200UL
+#define SPH_TWEAK_NO_CALL_AFTER_IUP               0x0000400UL
+#define SPH_TWEAK_NO_DELTAP_AFTER_IUP             0x0000800UL
+#define SPH_TWEAK_PIXEL_HINTING                   0x0001000UL
+#define SPH_TWEAK_RASTERIZER_35                   0x0002000UL
+#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES          0x0004000UL
+#define SPH_TWEAK_SKIP_IUP                        0x0008000UL
+#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES           0x0010000UL
+#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES           0x0020000UL
+#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK            0x0040000UL
+#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP    0x0080000UL
 
 
   FT_LOCAL( FT_Bool )