Merge "Update FreeType to 2.13.2" into main am: 2aeec9fb95 am: 6487a5bb15

Original change: https://android-review.googlesource.com/c/platform/external/freetype/+/2792273

Change-Id: I6e0198bf347cd2898db63dd4ae5e876b178e1391
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c51e136..bb078e2 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -76,7 +76,7 @@
 
 
 # Format of job names:
-# <OS> <Build-Tool> <Build-Params> <Architecture> 
+# <OS> <Build-Tool> <Build-Params> <Architecture>
 
 
 # Windows jobs.
diff --git a/.mailmap b/.mailmap
index 533274d..9c7d08f 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,7 +1,7 @@
+Alexander Borsuk <me@alex.bio> <alexander.borsuk@qnective.com>
 Behdad Esfahbod (بهداد اسفهبد) <behdad@behdad.org> <behdad.esfahbod@gmail.com>
 Behdad Esfahbod (بهداد اسفهبد) <behdad@behdad.org> <behdad@google.com>
 Behdad Esfahbod (بهداد اسفهبد) <behdad@behdad.org>
-Alexander Borsuk <me@alex.bio> <alexander.borsuk@qnective.com>
 Ewald Hew (Hew Yih Shiuan 丘毅宣) <ewaldhew@gmail.com>
 Moazin Khatti (موؤذن کھٹی) <moazinkhatri@gmail.com>
 Priyesh Kumar (प्रियेश कुमार) <priyeshkkumar@gmail.com>
@@ -15,6 +15,7 @@
 Suzuki, Toshiya (鈴木俊哉) <mpsuzuki@hiroshima-u.ac.jp> suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
 Bram Tassyns <bramt@enfocus.be> bram tassyns <BramT@enfocus.be>
 Bram Tassyns <bramt@enfocus.be> <BramT@enfocus.com>
+Anurag Thakur (अनुराग ठाकुर) <anuthadev@gmail.com>
 David Turner <david@freetype.org> <david.turner.dev@gmail.com>
 David Turner <david@freetype.org> <digit@google.com>
 Anuj Verma (अनुज वर्मा) <anujv@iitbhilai.ac.in>
diff --git a/Android.bp b/Android.bp
index 3680aff..cf537cb 100644
--- a/Android.bp
+++ b/Android.bp
@@ -226,7 +226,6 @@
         "src/gzip/crc32.h",  // No license header
         "src/gzip/ftzconf.h",
         "src/gzip/gzguts.h",
-        "src/gzip/infback.c",
         "src/gzip/inffast.c",
         "src/gzip/inffast.h",
         "src/gzip/inffixed.h",  // No license header
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 554b580..8dbca01 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -164,7 +164,7 @@
 
 set(VERSION_MAJOR "2")
 set(VERSION_MINOR "13")
-set(VERSION_PATCH "0")
+set(VERSION_PATCH "2")
 
 # Generate LIBRARY_VERSION and LIBRARY_SOVERSION.
 set(LIBTOOL_REGEX "version_info='([0-9]+):([0-9]+):([0-9]+)'")
diff --git a/LICENSE b/LICENSE
index 6089bcf..2ea854b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1263,17 +1263,6 @@
 Copyright (C) 2010-2023 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.
-
--------------------------------------------------------------------
-
-Copyright (C) 2010-2023 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
@@ -1716,6 +1705,27 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 2010, 2017 Craig A. Berry
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+-------------------------------------------------------------------
+
 Copyright (c) 2012, Intel Corporation
 Copyright (c) 2019 Sony Interactive Entertainment Inc.
 
diff --git a/METADATA b/METADATA
index 1d9bbd4..e715d6c 100644
--- a/METADATA
+++ b/METADATA
@@ -9,14 +9,14 @@
     type: GIT
     value: "git://git.sv.nongnu.org/freetype/freetype2.git"
   }
-  version: "0b62c1e43dc4b0e3c50662aac757e4f7321e5466"
+  version: "2.13.2"
   license_type: RESTRICTED
   last_upgrade_date {
-    year: 2022
-    month: 12
-    day: 14
+    year: 2023
+    month: 10
+    day: 17
   }
   security {
-      tag: "NVD-CPE2.3:cpe:/a:freetype:freetype:2.10.4"
+      tag: "NVD-CPE2.3:cpe:/a:freetype:freetype:2.13.2"
   }
 }
diff --git a/README b/README
index 327b94d..cd4c1d7 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-FreeType 2.13.0
+FreeType 2.13.2
 ===============
 
 Homepage: https://www.freetype.org
@@ -32,9 +32,9 @@
 
 and download one of the following files.
 
-  freetype-doc-2.13.0.tar.xz
-  freetype-doc-2.13.0.tar.gz
-  ftdoc2130.zip
+  freetype-doc-2.13.2.tar.xz
+  freetype-doc-2.13.2.tar.gz
+  ftdoc2132.zip
 
 To view the documentation online, go to
 
diff --git a/builds/freetype.mk b/builds/freetype.mk
index d96ded0..b3fac80 100644
--- a/builds/freetype.mk
+++ b/builds/freetype.mk
@@ -299,7 +299,7 @@
                   $(PUBLIC_DIR)/config/*.h \
                   $(PUBLIC_DIR)/cache/*.h
 	@echo Building static site...
-	cd $(DOC_DIR) && mkdocs build
+	cd $(DOC_DIR) && $(PYTHON) -m mkdocs build
 	@echo Done.
 
 # Variables for running `refdoc' with Python's `virtualenv'.  The
diff --git a/builds/mac/README b/builds/mac/README
index 092487a..06e3d51 100644
--- a/builds/mac/README
+++ b/builds/mac/README
@@ -200,14 +200,6 @@
   behaviours are not tested at all. Building ftdemos
   for classic MacOS and working test is required.
 
-  4-3. Porting Jam onto MPW
-  -------------------------
-
-  FreeType uses Jam (and FT-Jam) for unified cross-
-  platform building tool. At present, Jam is not ported
-  to MPW. To update classic MacOS support easily,
-  building by Jam is expected on MPW.
-
 
 APPENDIX I
 ----------
diff --git a/builds/meson/parse_modules_cfg.py b/builds/meson/parse_modules_cfg.py
index 6030bb2..d48129f 100644
--- a/builds/meson/parse_modules_cfg.py
+++ b/builds/meson/parse_modules_cfg.py
@@ -97,8 +97,12 @@
 
     for module in lists["AUX_MODULES"]:
         if module in ("psaux", "psnames", "otvalid", "gxvalid"):
+            name = {
+                "gxvalid": "gxv",
+                "otvalid": "otv",
+            }.get(module, module)
             result += (
-                "FT_USE_MODULE( FT_Module_Class, %s_module_class )\n" % module
+                "FT_USE_MODULE( FT_Module_Class, %s_module_class )\n" % name
             )
 
     result += "/* EOF */\n"
diff --git a/builds/toplevel.mk b/builds/toplevel.mk
index a0e0c87..8d5063e 100644
--- a/builds/toplevel.mk
+++ b/builds/toplevel.mk
@@ -198,27 +198,22 @@
 include $(TOP_DIR)/builds/modules.mk
 
 
-# get FreeType version string, using a
-# poor man's `sed' emulation with make's built-in string functions
+# get FreeType version string using built-in string functions
 #
+hash := \#
+
 work := $(strip $(shell $(CAT) \
                   $(subst /,$(SEP),$(TOP_DIR)/include/freetype/freetype.h)))
-work := $(subst |,x,$(work))
-work := $(subst $(space),|,$(work))
-work := $(subst \#define|FREETYPE_MAJOR|,$(space),$(work))
-work := $(word 2,$(work))
-major := $(subst |,$(space),$(work))
-major := $(firstword $(major))
 
-work := $(subst \#define|FREETYPE_MINOR|,$(space),$(work))
-work := $(word 2,$(work))
-minor := $(subst |,$(space),$(work))
-minor := $(firstword $(minor))
+work := $(subst $(hash)define$(space)FREETYPE_MAJOR$(space),MAjOR=,$(work))
+work := $(subst $(hash)define$(space)FREETYPE_MINOR$(space),MInOR=,$(work))
+work := $(subst $(hash)define$(space)FREETYPE_PATCH$(space),PAtCH=,$(work))
 
-work := $(subst \#define|FREETYPE_PATCH|,$(space),$(work))
-work := $(word 2,$(work))
-patch := $(subst |,$(space),$(work))
-patch := $(firstword $(patch))
+major := $(subst MAjOR=,,$(filter MAjOR=%,$(work)))
+minor := $(subst MInOR=,,$(filter MInOR=%,$(work)))
+patch := $(subst PAtCH=,,$(filter PAtCH=%,$(work)))
+
+work :=
 
 # ifneq ($(findstring x0x,x$(patch)x),)
 #   version := $(major).$(minor)
@@ -317,6 +312,6 @@
 	rm -f $(TOP_DIR)/docs/mkdocs.yml
 
 	@# Remove more stuff related to git.
-	rm -rf (TOP_DIR)/subprojects/dlg
+	rm -rf $(TOP_DIR)/subprojects/dlg
 
 # EOF
diff --git a/builds/unix/configure.raw b/builds/unix/configure.raw
index 8e98283..dc7426e 100644
--- a/builds/unix/configure.raw
+++ b/builds/unix/configure.raw
@@ -17,7 +17,7 @@
 
 # Don't forget to update `docs/VERSIONS.TXT'!
 
-version_info='25:0:19'
+version_info='26:1:20'
 AC_SUBST([version_info])
 ft_version=`echo $version_info | tr : .`
 AC_SUBST([ft_version])
@@ -966,14 +966,14 @@
 AX_PTHREAD([have_pthread=yes], [have_pthread=no])
 
 # Check for Python and docwriter
-
+PYTHON_MIN_VERSION=3.5
 have_py3=no
 have_docwriter=no
 PIP=pip
 
 AC_CHECK_PROGS([PYTHON], [python3 python], [missing])
 if test "x$PYTHON" != "xmissing"; then
-  AX_PROG_PYTHON_VERSION([3.5], [have_py3=yes], [])
+  AX_PROG_PYTHON_VERSION([$PYTHON_MIN_VERSION], [have_py3=yes], [])
 
   if test "x$have_py3" = "xyes"; then
     PIP="$PYTHON -m $PIP"
@@ -1162,7 +1162,7 @@
   `make refdoc' will fail since pip package `docwriter' is not installed.
   To install, run `$PIP install docwriter', or to use a Python
   virtual environment, run `make refdoc-venv' (requires pip package
-  `virtualenv').  These operations require Python >= 3.5.
+  `virtualenv').  These operations require Python >= $PYTHON_MIN_VERSION.
   ])
 fi
 
diff --git a/builds/vms/LIBS.OPT_IA64 b/builds/vms/LIBS.OPT_IA64
deleted file mode 100644
index 6768c76..0000000
--- a/builds/vms/LIBS.OPT_IA64
+++ /dev/null
Binary files differ
diff --git a/builds/vms/_LINK.OPT_IA64 b/builds/vms/_LINK.OPT_IA64
deleted file mode 100644
index b8cbd1b..0000000
--- a/builds/vms/_LINK.OPT_IA64
+++ /dev/null
Binary files differ
diff --git a/builds/vms/apinames_vms.bash b/builds/vms/apinames_vms.bash
new file mode 100644
index 0000000..e9b1b72
--- /dev/null
+++ b/builds/vms/apinames_vms.bash
@@ -0,0 +1,2 @@
+src/tools/apinames -wV include/freetype/*.h > freetype_vms0.opt
+mv freetype_vms0.opt freetype_vms.opt
diff --git a/builds/vms/vmslib.dat b/builds/vms/vmslib.dat
deleted file mode 100644
index 4c817da..0000000
--- a/builds/vms/vmslib.dat
+++ /dev/null
@@ -1,28 +0,0 @@
-!
-! This is a simple driver file with information used by make.com to
-! check if external libraries (like t1lib and freetype) are available on
-! the system.
-!
-! Layout of the file:
-!
-!    - Lines starting with ! are treated as comments
-!    - Elements in a data line are separated by # signs
-!    - The elements need to be listed in the following order
-!      1.) Name of the Library 
-!      2.) Location where the object library can be found
-!      3.) Location where the include files for the library can be found
-!      4.) Include file used to verify library location
-!      5.) CPP define to pass to the build to indicate availability of
-!          the library
-!
-! Example: The following  lines show how definitions
-!          might look like. They are site specific and the locations of the
-!          library and include files need almost certainly to be changed.
-!
-! Location: All of the libaries can be found at the following addresses
-!
-!   ZLIB:     http://www.decus.de:8080/www/vms/sw/zlib.htmlx
-!
-BZ2LIB # sys$library:libbz2.olb # decc$user_include: # bzlib.h # FT_CONFIG_OPTION_SYSTEM_ZLIB
-PNGLIB # sys$library:libpng.olb # sys$library: # png.h # FT_CONFIG_OPTION_SYSTEM_ZLIB
-ZLIB # sys$library:libz.olb # sys$library: # zlib.h # FT_CONFIG_OPTION_SYSTEM_ZLIB
diff --git a/builds/wince/vc2005-ce/index.html b/builds/wince/vc2005-ce/index.html
index 0a8b3c6..8ea6cfd 100644
--- a/builds/wince/vc2005-ce/index.html
+++ b/builds/wince/vc2005-ce/index.html
@@ -21,7 +21,7 @@
   <li>PPC/SP WM6 (Windows Mobile 6)</li>
 </ul>
 
-It compiles the following libraries from the FreeType 2.13.0 sources:</p>
+It compiles the following libraries from the FreeType 2.13.2 sources:</p>
 
 <ul>
   <pre>
diff --git a/builds/wince/vc2008-ce/index.html b/builds/wince/vc2008-ce/index.html
index 747370a..a6e74f8 100644
--- a/builds/wince/vc2008-ce/index.html
+++ b/builds/wince/vc2008-ce/index.html
@@ -21,7 +21,7 @@
   <li>PPC/SP WM6 (Windows Mobile 6)</li>
 </ul>
 
-It compiles the following libraries from the FreeType 2.13.0 sources:</p>
+It compiles the following libraries from the FreeType 2.13.2 sources:</p>
 
 <ul>
   <pre>
diff --git a/builds/windows/vc2010/freetype.vcxproj b/builds/windows/vc2010/freetype.vcxproj
index 4c9e2b4..671d124 100644
--- a/builds/windows/vc2010/freetype.vcxproj
+++ b/builds/windows/vc2010/freetype.vcxproj
@@ -168,7 +168,7 @@
       <WarningLevel>Level4</WarningLevel>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

       <CompileAs>Default</CompileAs>

-      <DisableSpecificWarnings>4001</DisableSpecificWarnings>

+      <DisableSpecificWarnings>4001;4267</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

       <ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>

       <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>

@@ -195,7 +195,7 @@
       <WarningLevel>Level4</WarningLevel>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

       <CompileAs>Default</CompileAs>

-      <DisableSpecificWarnings>4001</DisableSpecificWarnings>

+      <DisableSpecificWarnings>4001;4267</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

       <ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>

       <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>

@@ -248,7 +248,7 @@
       <WarningLevel>Level4</WarningLevel>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

       <CompileAs>Default</CompileAs>

-      <DisableSpecificWarnings>4001</DisableSpecificWarnings>

+      <DisableSpecificWarnings>4001;4267</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

       <ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>

       <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>

@@ -274,7 +274,7 @@
       <WarningLevel>Level4</WarningLevel>

       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>

       <CompileAs>Default</CompileAs>

-      <DisableSpecificWarnings>4001</DisableSpecificWarnings>

+      <DisableSpecificWarnings>4001;4267</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

       <ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>

       <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>

@@ -328,7 +328,7 @@
       <DisableLanguageExtensions>true</DisableLanguageExtensions>

       <WarningLevel>Level4</WarningLevel>

       <CompileAs>Default</CompileAs>

-      <DisableSpecificWarnings>4001</DisableSpecificWarnings>

+      <DisableSpecificWarnings>4001;4267</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

       <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>

       <IntrinsicFunctions>true</IntrinsicFunctions>

@@ -356,7 +356,7 @@
       <DisableLanguageExtensions>true</DisableLanguageExtensions>

       <WarningLevel>Level4</WarningLevel>

       <CompileAs>Default</CompileAs>

-      <DisableSpecificWarnings>4001</DisableSpecificWarnings>

+      <DisableSpecificWarnings>4001;4267</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

       <IntrinsicFunctions>true</IntrinsicFunctions>

     </ClCompile>

@@ -409,7 +409,7 @@
       <DisableLanguageExtensions>true</DisableLanguageExtensions>

       <WarningLevel>Level4</WarningLevel>

       <CompileAs>Default</CompileAs>

-      <DisableSpecificWarnings>4001</DisableSpecificWarnings>

+      <DisableSpecificWarnings>4001;4267</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

       <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>

       <IntrinsicFunctions>true</IntrinsicFunctions>

@@ -435,7 +435,7 @@
       <DisableLanguageExtensions>true</DisableLanguageExtensions>

       <WarningLevel>Level4</WarningLevel>

       <CompileAs>Default</CompileAs>

-      <DisableSpecificWarnings>4001</DisableSpecificWarnings>

+      <DisableSpecificWarnings>4001;4267</DisableSpecificWarnings>

       <MultiProcessorCompilation>true</MultiProcessorCompilation>

       <IntrinsicFunctions>true</IntrinsicFunctions>

     </ClCompile>

diff --git a/builds/windows/vc2010/index.html b/builds/windows/vc2010/index.html
index c03be77..ee9b59a 100644
--- a/builds/windows/vc2010/index.html
+++ b/builds/windows/vc2010/index.html
@@ -12,7 +12,7 @@
 <p>This directory contains solution and project files for
 Visual&nbsp;C++&nbsp;2010 or newer, named <tt>freetype.sln</tt>,
 and <tt>freetype.vcxproj</tt>.  It compiles the following libraries
-from the FreeType 2.13.0 sources:</p>
+from the FreeType 2.13.2 sources:</p>
 
 <ul>
   <li>freetype.dll using 'Release' or 'Debug' configurations</li>
diff --git a/builds/windows/visualc/index.html b/builds/windows/visualc/index.html
index 6a70b34..816605e 100644
--- a/builds/windows/visualc/index.html
+++ b/builds/windows/visualc/index.html
@@ -12,7 +12,7 @@
 <p>This directory contains project files <tt>freetype.dsp</tt> for
 Visual C++ 6.0, and <tt>freetype.vcproj</tt> for Visual C++ 2002
 through 2008, which you might need to upgrade automatically.
-It compiles the following libraries from the FreeType 2.13.0 sources:</p>
+It compiles the following libraries from the FreeType 2.13.2 sources:</p>
 
 <ul>
   <li>freetype.dll using 'Release' or 'Debug' configurations</li>
diff --git a/builds/windows/visualce/index.html b/builds/windows/visualce/index.html
index cebab29..d9c8fe4 100644
--- a/builds/windows/visualce/index.html
+++ b/builds/windows/visualce/index.html
@@ -21,7 +21,7 @@
   <li>PPC/SP WM6 (Windows Mobile 6)</li>
 </ul>
 
-It compiles the following libraries from the FreeType 2.13.0 sources:</p>
+It compiles the following libraries from the FreeType 2.13.2 sources:</p>
 
 <ul>
   <pre>
diff --git a/configure b/configure
index 75f8b7b..d4315bd 100755
--- a/configure
+++ b/configure
@@ -18,7 +18,7 @@
 # respect GNUMAKE environment variable for backward compatibility
 if test "x$GNUMAKE" = x; then
   if test "x$MAKE" = x; then
-    if test "x`make -v 2>/dev/null | grep -E 'GNU|makepp'`" = x; then
+    if test "x`make -v 2>/dev/null | sed -n -e '/GNU/p' -e '/makepp/p'`" = x; then
       MAKE=gmake
     else
       MAKE=make
@@ -28,7 +28,7 @@
   MAKE=$GNUMAKE
 fi
 
-if test "x`$MAKE -v 2>/dev/null | grep -E 'GNU|makepp'`" = x; then
+if test "x`$MAKE -v 2>/dev/null | sed -n -e '/GNU/p' -e '/makepp/p'`" = x; then
   echo "GNU make (>= 3.81) or makepp (>= 2.0) is required to build FreeType2." >&2
   echo "Please try" >&2
   echo >&2
diff --git a/devel-teeui/rules.mk b/devel-teeui/rules.mk
index b834ce7..27b305a 100644
--- a/devel-teeui/rules.mk
+++ b/devel-teeui/rules.mk
@@ -11,6 +11,7 @@
 	$(FREETYPE_ROOT)/src/base/ftbase.c \
 	$(FREETYPE_ROOT)/src/base/ftbbox.c \
 	$(FREETYPE_ROOT)/src/base/ftglyph.c \
+	$(FREETYPE_ROOT)/src/base/ftmm.c \
 	$(FREETYPE_ROOT)/src/base/ftbitmap.c \
 	$(FREETYPE_ROOT)/src/sfnt/sfnt.c \
 	$(FREETYPE_ROOT)/src/truetype/truetype.c \
diff --git a/devel/ftoption.h b/devel/ftoption.h
index 1ae9b1a..da56abc 100644
--- a/devel/ftoption.h
+++ b/devel/ftoption.h
@@ -661,36 +661,12 @@
    * not) instructions in a certain way so that all TrueType fonts look like
    * they do in a Windows ClearType (DirectWrite) environment.  See [1] for a
    * technical overview on what this means.  See `ttinterp.h` for more
-   * details on the LEAN option.
+   * details on this option.
    *
-   * There are three possible values.
-   *
-   * Value 1:
-   *   This value is associated with the 'Infinality' moniker, contributed by
-   *   an individual nicknamed Infinality with the goal of making TrueType
-   *   fonts render better than on Windows.  A high amount of configurability
-   *   and flexibility, down to rules for single glyphs in fonts, but also
-   *   very slow.  Its experimental and slow nature and the original
-   *   developer losing interest meant that this option was never enabled in
-   *   default builds.
-   *
-   *   The corresponding interpreter version is v38.
-   *
-   * Value 2:
-   *   The new default mode for the TrueType driver.  The Infinality code
-   *   base was stripped to the bare minimum and all configurability removed
-   *   in the name of speed and simplicity.  The configurability was mainly
-   *   aimed at legacy fonts like 'Arial', 'Times New Roman', or 'Courier'.
-   *   Legacy fonts are fonts that modify vertical stems to achieve clean
-   *   black-and-white bitmaps.  The new mode focuses on applying a minimal
-   *   set of rules to all fonts indiscriminately so that modern and web
-   *   fonts render well while legacy fonts render okay.
-   *
-   *   The corresponding interpreter version is v40.
-   *
-   * Value 3:
-   *   Compile both, making both v38 and v40 available (the latter is the
-   *   default).
+   * The new default mode focuses on applying a minimal set of rules to all
+   * fonts indiscriminately so that modern and web fonts render well while
+   * legacy fonts render okay.  The corresponding interpreter version is v40.
+   * The so-called Infinality mode (v38) is no longer available in FreeType.
    *
    * By undefining these, you get rendering behavior like on Windows without
    * ClearType, i.e., Windows XP without ClearType enabled and Win9x
@@ -705,9 +681,7 @@
    * [1]
    * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
    */
-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  1     */
-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  2     */
-#define TT_CONFIG_OPTION_SUBPIXEL_HINTING     ( 1 | 2 )
+#define TT_CONFIG_OPTION_SUBPIXEL_HINTING
 
 
   /**************************************************************************
@@ -977,22 +951,15 @@
 
 
   /*
-   * The next three macros are defined if native TrueType hinting is
+   * The next two macros are defined if native TrueType hinting is
    * requested by the definitions above.  Don't change this.
    */
 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 #define  TT_USE_BYTECODE_INTERPRETER
-
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1
-#define  TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-#endif
-
-#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2
 #define  TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
 #endif
 #endif
-#endif
 
 
   /*
diff --git a/docs/CHANGES b/docs/CHANGES
index 3c6a877..96cf607 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -1,3 +1,57 @@
+CHANGES BETWEEN 2.13.1 and 2.13.2 (2023-Aug-25)
+
+  I. MISCELLANEOUS
+
+  - Better support for CFF2 variation fonts.
+
+  - TrueType interpreter  version 38 (also known  as 'Infinality') has
+    been removed.
+
+  - Improved OpenVMS support.
+
+
+======================================================================
+
+CHANGES BETWEEN 2.13.0 and 2.13.1 (2023-Jun-24)
+
+  I. MISCELLANEOUS
+
+  - New function  `FT_Get_Default_Named_Instance` to get the  index of
+    the default named instance of an OpenType Variation Font.
+
+  - A new load flag `FT_LOAD_NO_SVG` to make FreeType ignore glyphs in
+    an 'SVG ' table.
+
+  - New  function  `FT_GlyphSlot_AdjustWeight`  to  adjust  the  glyph
+    weight either  horizontally or  vertically.  This  is part  of the
+    `ftsynth.h` header file, which is  still considered to be in alpha
+    stage.
+
+  - TrueType interpreter  version 38 (also known  as 'Infinality') has
+    been deactivated; the value  of `TT_INTERPRETER_VERSION_38` is now
+    the same as `TT_INTERPRETER_VERSION_40`.
+
+  - Updated OpenVMS support.
+
+  - The  base  API  documentation  has  been  modularized  for  easier
+    handling.
+
+  - Switching named instances on and  off in Variation Fonts was buggy
+    if the design coordinates didn't change.
+
+  - `ftbench`  has a  new  command-line option  `-a`  to apply  design
+    coordinates.
+
+  - `ftview` can now flip SVG rendering on and off using the 'Z' key.
+
+  - In  `ftmulti` it  is  now possible  to toggle  the  fill rule  and
+    overlap flag  used for  rendering glyphs using  the 'F3'  and 'F4'
+    keys,  respectively.   Toggling  the anti-aliased  mode  has  been
+    changed to the 'TAB' key.
+
+
+======================================================================
+
 CHANGES BETWEEN 2.12.1 and 2.13.0 (2023-Feb-09)
 
   I. IMPORTANT CHANGES
@@ -12,7 +66,7 @@
       https://learn.microsoft.com/en-us/typography/opentype/spec/colr
 
 
-  III. MISCELLANEOUS
+  II. MISCELLANEOUS
 
   - For  OpenType  Variable Fonts,  `avar`  table  format 2.0  is  now
     supported.  The code was contributed by Behdad Esfahbod.
@@ -75,6 +129,10 @@
     af_debug_hints_
     ```
 
+  - The internal  zlib library was  updated to version  1.2.13.  Note,
+    however, that  FreeType is *not* affected  by CVE-2022-37434 since
+    it doesn't use the `inflateGetHeader` function.
+
 
 ======================================================================
 
@@ -2420,7 +2478,7 @@
       is provided for x86 and ARM.  See FT_CONFIG_OPTION_INLINE_MULFIX
       and FT_CONFIG_OPTION_NO_ASSEMBLER (in ftoption.h) for more.
 
-    - The handling of `tricky' fonts  (this is, fonts which don't work
+    - The handling of `tricky' fonts  (that is, fonts which don't work
       with the  autohinter, needing the font  format's hinting engine)
       has been generalized and changed slightly:
 
@@ -2877,7 +2935,7 @@
 
   II. IMPORTANT CHANGES
 
-    - Version 2.2 no longer exposes its internals, this is, the header
+    - Version 2.2 no longer exposes its internals, that is, the header
       files  located in  the `include/freetype/internal'  directory of
       the source package are not  copied anymore by the `make install'
       command.  Consequently, a number of rogue clients which directly
diff --git a/docs/DEBUG b/docs/DEBUG
index 4a5ac3a..7398df6 100644
--- a/docs/DEBUG
+++ b/docs/DEBUG
@@ -270,12 +270,12 @@
     `FT2_DEBUG' environment  variable.  Use this function  to override
     the value with `level'.  Use value `NULL' to disable tracing.
 
-  FT_Trace_Set_Default_Level():
+  FT_Trace_Set_Default_Level( void )
 
     Reset the tracing levels to the default value, i.e., the value of
     the `FT2_DEBUG' environment variable or no tracing if not set.
 
-  FT_Set_Log_Handler( ft_custom_log_handler  handler ):
+  FT_Set_Log_Handler( ft_custom_log_handler  handler )
 
     Use `handler' as a custom handler for formatting tracing and error
     messages.  The  `ft_custom_log_handler' typedef has  the following
@@ -290,7 +290,7 @@
    first argument  of `FT_TRACE' or  `FT_ERROR', and `args'  holds the
    remaining arguments.
 
-  FT_Set_Default_Log_Handler():
+  FT_Set_Default_Log_Handler( void )
 
     Reset the log handler to the default version.
 
diff --git a/docs/INSTALL.VMS b/docs/INSTALL.VMS
index 4ed4016..4f8c3ac 100644
--- a/docs/INSTALL.VMS
+++ b/docs/INSTALL.VMS
@@ -1,23 +1,23 @@
-How to build the FreeType 2 library on VMS
------------------------------------------
+How to build the FreeType library on VMS
+----------------------------------------
 
-It is actually very straightforward to install the FreeType 2 library.
-Just  execute vms_make.com from  the toplevel  directory to  build the
+It is actually  very straightforward to install  the FreeType library.
+Just execute `vms_make.com  from` the toplevel directory  to build the
 library.  This procedure currently accepts the following options:
 
-DEBUG
+* `DEBUG`
   Build the library with debug information and without optimization.
 
-lopts=<value>
-  Options to pass to the link command e.g. lopts=/traceback
+* `lopts=<value>`
+  Options to pass to the link command, e.g., `lopts=/traceback`.
 
-ccopt=<value>
-  Options to pass to the C compiler e.g. ccopt=/float=ieee
+* `ccopt=<value>`
+  Options to pass to the C compiler, e.g., `ccopt=/float=ieee`.
 
 In case you did download the demos, place them in a separate directory
-sharing the same top level  as the directory of FreeType 2  and follow
-the same instructions as above for  the demos from  there.  The  build
-process relies on this  to figure out  the location  of the FreeType 2
+sharing the same top level as the directory of FreeType and follow the
+same  instructions as  above  for  the demos  from  there.  The  build
+process relies  on this  to figure  out the  location of  the FreeType
 include files.
 
 
@@ -28,24 +28,31 @@
 
   [.LIB]
 
-To  compile applications  using  FreeType  2 you  have  to define  the
-logical FREETYPE pointing to the directory
+To compile applications using FreeType  you have to define the logical
+`FREETYPE` pointing to the directory
 
   [.INCLUDE.FREETYPE]
 
-i.e., if  the directory in which  this INSTALL.VMS file  is located is
-$disk:[freetype] then define the logical with
+i.e., if the directory in which  this `INSTALL.VMS` file is located is
+`$disk:[freetype.docs]`, then define the logical with
 
   define freetype $disk:[freetype.include.freetype]
 
-This version has  been tested with Compaq C  V6.2-006 on OpenVMS Alpha
-V7.2-1.
+See  http://nchrem.tnw.tudelft.nl/openvms/software2.html#Freetype  for
+the packages FreeType depends on.
+
+The latest versions were tested using
+  - VSI C V7.4-002 and DECWindows V1.7-F on OpenVMS Alpha V8.4-2L1
+  - VSI C V7.4-001 and DECWindows V1.7-E on OpenVMS IA64 V8.4-2L3
 
 
-  Any problems can be reported to
+Any problems can be reported to
 
-    Jouk Jansen <joukj@hrem.stm.tudelft.nl> or
-    Martin P.J. Zinser <zinser@zinser.no-ip.info>
+  Jouk Jansen <joukj@hrem.nano.tudelft.nl> or
+
+Orginal version of the build procedures was created by
+
+  Martin P.J. Zinser <zinser@zinser.no-ip.info>
 
 ------------------------------------------------------------------------
 
diff --git a/docs/README b/docs/README
index d71fd37..c2b5af8 100644
--- a/docs/README
+++ b/docs/README
@@ -18,8 +18,6 @@
     - This may or may not require internet access every time depending on
     pip and system caching.
 
-This also works with Jam: Just type `jam refdoc' in the main directory.
-
 Some troubleshooting tips:
 
 * Regularly run `pip install --upgrade docwriter' to check for updates which
diff --git a/docs/VERSIONS.TXT b/docs/VERSIONS.TXT
index 92f6a8c..8b43c15 100644
--- a/docs/VERSIONS.TXT
+++ b/docs/VERSIONS.TXT
@@ -60,6 +60,8 @@
 
     release     libtool     so
   -------------------------------
+     2.13.2     26.1.20   6.20.1
+     2.13.1     26.0.20   6.20.0
      2.13.0     25.0.19   6.19.0
      2.12.1     24.3.18   6.18.3
      2.12.0     24.2.18   6.18.2
diff --git a/docs/formats.txt b/docs/formats.txt
index 7a4bae0..882d62d 100644
--- a/docs/formats.txt
+++ b/docs/formats.txt
@@ -57,7 +57,7 @@
   (`*') in the table below.
 
   FreeType can  be configured to  support Mac  files (on older  Mac OS
-  versions, a `file' is stored as a data and a resource fork, this is,
+  versions, a `file' is stored as a data and a resource fork, that is,
   within two  separate data chunks).  If  a file can't be  opened as a
   font, FreeType then checks whether it  is a resource fork, trying to
   extract  the contained  font data  from  either a  `POST' or  `sfnt'
@@ -77,8 +77,8 @@
   ---     BDF     ---     ---        bdf      5005.BDF_Spec.pdf, X11
 
 
-  SFNT    PS      TYPE_1  ---        type1    Type 1 GX Font Format
-                                              (for the Mac) [3]
+  SFNT    PS      TYPE_1  ---        type1    Type 1 GX Font Format [7]
+                                              (for the Mac; not supported)
   SFNT    PS      TYPE_1  CID        cid      5180.sfnt.pdf (for the Mac) [3]
   SFNT    PS      CFF     ---        cff      OT spec, 5176.CFF.pdf
                                               (`OTTO' format)
@@ -198,6 +198,12 @@
 [6] Supported  font  formats  are   TrueType  and  OpenType  fonts  as
     defined in the OpenType specification 1.6 and newer.
 
+[7] `The Type 1 GX Font Format' (dated 1995-09-27)  was distributed in
+    Apple Developer CD-ROM in those days.  The content of `TYP1' table
+    is a PostScript Type 1 font without the eexec encryption.  Current
+    versions of FreeType don't not support this format,  but FontForge
+    can load it.
+
 ------------------------------------------------------------------------
 
 Copyright (C) 2004-2023 by
diff --git a/docs/freetype-config.1 b/docs/freetype-config.1
index 6459431..6ef1ac8 100644
--- a/docs/freetype-config.1
+++ b/docs/freetype-config.1
@@ -1,4 +1,4 @@
-.TH FREETYPE-CONFIG 1 "February 2023" "FreeType 2.13.0"
+.TH FREETYPE-CONFIG 1 "August 2023" "FreeType 2.13.2"
 .
 .
 .SH NAME
diff --git a/docs/release b/docs/release
index fec91e8..c296efc 100644
--- a/docs/release
+++ b/docs/release
@@ -15,33 +15,53 @@
 
 . docs/VERSIONS.TXT: Document changed `version_info`.
 
-. Clone the git archive to another directory with
+. Update the 'dlg' submodule with
 
-    git clone -l -s . ../freetype.test
+    git submodule foreach git pull origin master
 
-  or something like this and run
+. Copy the submodule code with
 
-    make distclean; make devel; make
-    make distclean; make devel; make multi
-    make distclean; make devel CC=g++; make CC=g++
-    make distclean; make devel CC=g++; make multi CC=g++
+    make copy_submodule
+
+  and run
+
+    make distclean && make devel && make
+    make distclean && make devel && make multi
+    make distclean && make devel CC=g++ && make CC=g++ ANSIFLAGS=""
+    make distclean && make devel CC=g++ && make multi CC=g++ ANSIFLAGS=""
 
     sh autogen.sh
-    make distclean; ./configure CC=g++; make
+    make distclean && ./configure CC=g++ && make ANSIFLAGS=""
 
-  in the cloned repository to test compilation with both gcc and g++.
+  to test compilation with both gcc and g++ (you might also add the `-j`
+  flag to `make` for parallel compilation).
 
   Note that it is normally not necessary to test standard C
   compilation with the `configure`, `meson`, and `cmake` build tools
-  since this is done by the CI process of 'gitlab.freetype.org' for
+  since this is done by the CI process of 'gitlab.freedesktop.org' for
   every commit.
 
-. Test C++ compilation for 'freetype-demos' too (using `git clone` as
-  above).
+. Test C++ compilation for 'freetype-demos' too; this needs a compiled
+  FreeType library as described in the `README` file.
+
+    make distclean && make
+    make distclean && make CC=g++ ANSIFLAGS=""
 
 . Run `src/tools/chktrcmp.py` and check that there are no undefined
   `trace_XXXX` macros.
 
+. Update meson subproject files (for both the 'freetype' and
+  'freetype-demos' git repositories) with
+
+    meson subprojects update
+
+. Test meson compilation (for both the 'freetype' and 'freetype-demos'
+  git repositories) with
+
+    meson setup builddir && meson compile -C builddir
+
+. Commit everything.
+
 . After pushing the new release, tag the git repositories ('freetype',
   'freetype-demos') with
 
diff --git a/generate_notice.py b/generate_notice.py
index 26d3939..16f4e70 100644
--- a/generate_notice.py
+++ b/generate_notice.py
@@ -61,9 +61,7 @@
   "builds/mac/ftlib.prj.xml",
   "builds/unix/.gitignore",
   "builds/unix/freetype2.in",
-  "builds/vms/LIBS.OPT_IA64",
-  "builds/vms/_LINK.OPT_IA64",
-  "builds/vms/vmslib.dat",
+  "builds/vms/apinames_vms.bash",
   "builds/wince/vc2005-ce/freetype.sln",
   "builds/wince/vc2005-ce/freetype.vcproj",
   "builds/wince/vc2005-ce/index.html",
diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h
index 9a12bab..ea86c0c 100644
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -664,36 +664,12 @@
    * not) instructions in a certain way so that all TrueType fonts look like
    * they do in a Windows ClearType (DirectWrite) environment.  See [1] for a
    * technical overview on what this means.  See `ttinterp.h` for more
-   * details on the LEAN option.
+   * details on this option.
    *
-   * There are three possible values.
-   *
-   * Value 1:
-   *   This value is associated with the 'Infinality' moniker, contributed by
-   *   an individual nicknamed Infinality with the goal of making TrueType
-   *   fonts render better than on Windows.  A high amount of configurability
-   *   and flexibility, down to rules for single glyphs in fonts, but also
-   *   very slow.  Its experimental and slow nature and the original
-   *   developer losing interest meant that this option was never enabled in
-   *   default builds.
-   *
-   *   The corresponding interpreter version is v38.
-   *
-   * Value 2:
-   *   The new default mode for the TrueType driver.  The Infinality code
-   *   base was stripped to the bare minimum and all configurability removed
-   *   in the name of speed and simplicity.  The configurability was mainly
-   *   aimed at legacy fonts like 'Arial', 'Times New Roman', or 'Courier'.
-   *   Legacy fonts are fonts that modify vertical stems to achieve clean
-   *   black-and-white bitmaps.  The new mode focuses on applying a minimal
-   *   set of rules to all fonts indiscriminately so that modern and web
-   *   fonts render well while legacy fonts render okay.
-   *
-   *   The corresponding interpreter version is v40.
-   *
-   * Value 3:
-   *   Compile both, making both v38 and v40 available (the latter is the
-   *   default).
+   * The new default mode focuses on applying a minimal set of rules to all
+   * fonts indiscriminately so that modern and web fonts render well while
+   * legacy fonts render okay.  The corresponding interpreter version is v40.
+   * The so-called Infinality mode (v38) is no longer available in FreeType.
    *
    * By undefining these, you get rendering behavior like on Windows without
    * ClearType, i.e., Windows XP without ClearType enabled and Win9x
@@ -708,12 +684,8 @@
    * [1]
    * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
    */
-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  1         */
-
 /* ANDROID: disabled */
-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  2         */
-
-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  ( 1 | 2 ) */
+/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING            */
 
 
   /**************************************************************************
@@ -983,22 +955,15 @@
 
 
   /*
-   * The next three macros are defined if native TrueType hinting is
+   * The next two macros are defined if native TrueType hinting is
    * requested by the definitions above.  Don't change this.
    */
 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 #define  TT_USE_BYTECODE_INTERPRETER
-
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1
-#define  TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-#endif
-
-#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2
 #define  TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
 #endif
 #endif
-#endif
 
 
   /*
diff --git a/include/freetype/config/ftstdlib.h b/include/freetype/config/ftstdlib.h
index 3c9d2ae..f65148a 100644
--- a/include/freetype/config/ftstdlib.h
+++ b/include/freetype/config/ftstdlib.h
@@ -111,13 +111,13 @@
 
 #include <stdio.h>
 
-#define FT_FILE     FILE
-#define ft_fclose   fclose
-#define ft_fopen    fopen
-#define ft_fread    fread
-#define ft_fseek    fseek
-#define ft_ftell    ftell
-#define ft_sprintf  sprintf
+#define FT_FILE      FILE
+#define ft_fclose    fclose
+#define ft_fopen     fopen
+#define ft_fread     fread
+#define ft_fseek     fseek
+#define ft_ftell     ftell
+#define ft_snprintf  snprintf
 
 
   /**************************************************************************
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index efff74f..92acf37 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -102,61 +102,25 @@
    */
 
 
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*                                                                       */
-  /*                        B A S I C   T Y P E S                          */
-  /*                                                                       */
-  /*************************************************************************/
-  /*************************************************************************/
-
-
   /**************************************************************************
    *
    * @section:
-   *   base_interface
+   *   font_testing_macros
    *
    * @title:
-   *   Base Interface
+   *   Font Testing Macros
    *
    * @abstract:
-   *   The FreeType~2 base font interface.
+   *   Macros to test various properties of fonts.
    *
    * @description:
-   *   This section describes the most important public high-level API
-   *   functions of FreeType~2.
+   *   Macros to test the most important font properties.
+   *
+   *   It is recommended to use these high-level macros instead of directly
+   *   testing the corresponding flags, which are scattered over various
+   *   structures.
    *
    * @order:
-   *   FT_Library
-   *   FT_Face
-   *   FT_Size
-   *   FT_GlyphSlot
-   *   FT_CharMap
-   *   FT_Encoding
-   *   FT_ENC_TAG
-   *
-   *   FT_FaceRec
-   *
-   *   FT_FACE_FLAG_SCALABLE
-   *   FT_FACE_FLAG_FIXED_SIZES
-   *   FT_FACE_FLAG_FIXED_WIDTH
-   *   FT_FACE_FLAG_HORIZONTAL
-   *   FT_FACE_FLAG_VERTICAL
-   *   FT_FACE_FLAG_COLOR
-   *   FT_FACE_FLAG_SFNT
-   *   FT_FACE_FLAG_CID_KEYED
-   *   FT_FACE_FLAG_TRICKY
-   *   FT_FACE_FLAG_KERNING
-   *   FT_FACE_FLAG_MULTIPLE_MASTERS
-   *   FT_FACE_FLAG_VARIATION
-   *   FT_FACE_FLAG_GLYPH_NAMES
-   *   FT_FACE_FLAG_EXTERNAL_STREAM
-   *   FT_FACE_FLAG_HINTER
-   *   FT_FACE_FLAG_SVG
-   *   FT_FACE_FLAG_SBIX
-   *   FT_FACE_FLAG_SBIX_OVERLAY
-   *
    *   FT_HAS_HORIZONTAL
    *   FT_HAS_VERTICAL
    *   FT_HAS_KERNING
@@ -176,21 +140,59 @@
    *   FT_IS_NAMED_INSTANCE
    *   FT_IS_VARIATION
    *
-   *   FT_STYLE_FLAG_BOLD
-   *   FT_STYLE_FLAG_ITALIC
+   */
+
+
+  /**************************************************************************
    *
-   *   FT_SizeRec
-   *   FT_Size_Metrics
+   * @section:
+   *   library_setup
    *
-   *   FT_GlyphSlotRec
-   *   FT_Glyph_Metrics
-   *   FT_SubGlyph
+   * @title:
+   *   Library Setup
    *
-   *   FT_Bitmap_Size
+   * @abstract:
+   *   Functions to start and end the usage of the FreeType library.
    *
+   * @description:
+   *   Functions to start and end the usage of the FreeType library.
+   *
+   *   Note that @FT_Library_Version and @FREETYPE_XXX are of limited use
+   *   because even a new release of FreeType with only documentation
+   *   changes increases the version number.
+   *
+   * @order:
+   *   FT_Library
    *   FT_Init_FreeType
    *   FT_Done_FreeType
    *
+   *   FT_Library_Version
+   *   FREETYPE_XXX
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   face_creation
+   *
+   * @title:
+   *   Face Creation
+   *
+   * @abstract:
+   *   Functions to manage fonts.
+   *
+   * @description:
+   *   The functions and structures collected in this section operate on
+   *   fonts globally.
+   *
+   * @order:
+   *   FT_Face
+   *   FT_FaceRec
+   *   FT_FACE_FLAG_XXX
+   *   FT_STYLE_FLAG_XXX
+   *
    *   FT_New_Face
    *   FT_Done_Face
    *   FT_Reference_Face
@@ -198,10 +200,36 @@
    *   FT_Face_Properties
    *   FT_Open_Face
    *   FT_Open_Args
+   *   FT_OPEN_XXX
    *   FT_Parameter
    *   FT_Attach_File
    *   FT_Attach_Stream
    *
+   */
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   sizing_and_scaling
+   *
+   * @title:
+   *   Sizing and Scaling
+   *
+   * @abstract:
+   *   Functions to manage font sizes.
+   *
+   * @description:
+   *   The functions and structures collected in this section are related to
+   *   selecting and manipulating the size of a font globally.
+   *
+   * @order:
+   *   FT_Size
+   *   FT_SizeRec
+   *   FT_Size_Metrics
+   *
+   *   FT_Bitmap_Size
+   *
    *   FT_Set_Char_Size
    *   FT_Set_Pixel_Sizes
    *   FT_Request_Size
@@ -209,44 +237,37 @@
    *   FT_Size_Request_Type
    *   FT_Size_RequestRec
    *   FT_Size_Request
+   *
    *   FT_Set_Transform
    *   FT_Get_Transform
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   glyph_retrieval
+   *
+   * @title:
+   *   Glyph Retrieval
+   *
+   * @abstract:
+   *   Functions to manage glyphs.
+   *
+   * @description:
+   *   The functions and structures collected in this section operate on
+   *   single glyphs, of which @FT_Load_Glyph is most important.
+   *
+   * @order:
+   *   FT_GlyphSlot
+   *   FT_GlyphSlotRec
+   *   FT_Glyph_Metrics
+   *
    *   FT_Load_Glyph
-   *   FT_Get_Char_Index
-   *   FT_Get_First_Char
-   *   FT_Get_Next_Char
-   *   FT_Load_Char
-   *
-   *   FT_OPEN_MEMORY
-   *   FT_OPEN_STREAM
-   *   FT_OPEN_PATHNAME
-   *   FT_OPEN_DRIVER
-   *   FT_OPEN_PARAMS
-   *
-   *   FT_LOAD_DEFAULT
-   *   FT_LOAD_RENDER
-   *   FT_LOAD_MONOCHROME
-   *   FT_LOAD_LINEAR_DESIGN
-   *   FT_LOAD_NO_SCALE
-   *   FT_LOAD_NO_HINTING
-   *   FT_LOAD_NO_BITMAP
-   *   FT_LOAD_SBITS_ONLY
-   *   FT_LOAD_NO_AUTOHINT
-   *   FT_LOAD_COLOR
-   *
-   *   FT_LOAD_VERTICAL_LAYOUT
-   *   FT_LOAD_IGNORE_TRANSFORM
-   *   FT_LOAD_FORCE_AUTOHINT
-   *   FT_LOAD_NO_RECURSE
-   *   FT_LOAD_PEDANTIC
-   *
-   *   FT_LOAD_TARGET_NORMAL
-   *   FT_LOAD_TARGET_LIGHT
-   *   FT_LOAD_TARGET_MONO
-   *   FT_LOAD_TARGET_LCD
-   *   FT_LOAD_TARGET_LCD_V
-   *
+   *   FT_LOAD_XXX
    *   FT_LOAD_TARGET_MODE
+   *   FT_LOAD_TARGET_XXX
    *
    *   FT_Render_Glyph
    *   FT_Render_Mode
@@ -254,34 +275,121 @@
    *   FT_Kerning_Mode
    *   FT_Get_Track_Kerning
    *
+   */
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   character_mapping
+   *
+   * @title:
+   *   Character Mapping
+   *
+   * @abstract:
+   *   Functions to manage character-to-glyph maps.
+   *
+   * @description:
+   *   This section holds functions and structures that are related to
+   *   mapping character input codes to glyph indices.
+   *
+   *   Note that for many scripts the simplistic approach used by FreeType
+   *   of mapping a single character to a single glyph is not valid or
+   *   possible!  In general, a higher-level library like HarfBuzz or ICU
+   *   should be used for handling text strings.
+   *
+   * @order:
+   *   FT_CharMap
    *   FT_CharMapRec
+   *   FT_Encoding
+   *   FT_ENC_TAG
+   *
    *   FT_Select_Charmap
    *   FT_Set_Charmap
    *   FT_Get_Charmap_Index
    *
+   *   FT_Get_Char_Index
+   *   FT_Get_First_Char
+   *   FT_Get_Next_Char
+   *   FT_Load_Char
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   information_retrieval
+   *
+   * @title:
+   *   Information Retrieval
+   *
+   * @abstract:
+   *   Functions to retrieve font and glyph information.
+   *
+   * @description:
+   *   Functions to retrieve font and glyph information.  Only some very
+   *   basic data is covered; see also the chapter on the format-specific
+   *   API for more.
+   *
+   *
+   * @order:
    *   FT_Get_Name_Index
    *   FT_Get_Glyph_Name
    *   FT_Get_Postscript_Name
    *   FT_Get_FSType_Flags
+   *   FT_FSTYPE_XXX
    *   FT_Get_SubGlyph_Info
+   *   FT_SUBGLYPH_FLAG_XXX
    *
+   */
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   other_api_data
+   *
+   * @title:
+   *   Other API Data
+   *
+   * @abstract:
+   *   Other structures, enumerations, and macros.
+   *
+   * @description:
+   *   Other structures, enumerations, and macros.  Deprecated functions are
+   *   also listed here.
+   *
+   * @order:
    *   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_SubGlyph
    *
    *   FT_HAS_FAST_GLYPHS
+   *   FT_Face_CheckTrueTypePatents
+   *   FT_Face_SetUnpatentedHinting
    *
    */
 
 
+  /*************************************************************************/
+  /*************************************************************************/
+  /*                                                                       */
+  /*                        B A S I C   T Y P E S                          */
+  /*                                                                       */
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   glyph_retrieval
+   *
+   */
+
   /**************************************************************************
    *
    * @struct:
@@ -351,6 +459,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   sizing_and_scaling
+   *
+   */
+
+  /**************************************************************************
+   *
    * @struct:
    *   FT_Bitmap_Size
    *
@@ -411,6 +526,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   library_setup
+   *
+   */
+
+  /**************************************************************************
+   *
    * @type:
    *   FT_Library
    *
@@ -483,7 +605,7 @@
   /**************************************************************************
    *
    * @section:
-   *   base_interface
+   *   face_creation
    *
    */
 
@@ -521,6 +643,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   sizing_and_scaling
+   *
+   */
+
+  /**************************************************************************
+   *
    * @type:
    *   FT_Size
    *
@@ -553,6 +682,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   glyph_retrieval
+   *
+   */
+
+  /**************************************************************************
+   *
    * @type:
    *   FT_GlyphSlot
    *
@@ -572,6 +708,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   character_mapping
+   *
+   */
+
+  /**************************************************************************
+   *
    * @type:
    *   FT_CharMap
    *
@@ -879,6 +1022,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   other_api_data
+   *
+   */
+
+  /**************************************************************************
+   *
    * @type:
    *   FT_Face_Internal
    *
@@ -894,6 +1044,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   face_creation
+   *
+   */
+
+  /**************************************************************************
+   *
    * @struct:
    *   FT_FaceRec
    *
@@ -918,7 +1075,7 @@
    *     If we have the third named instance of face~4, say, `face_index` is
    *     set to 0x00030004.
    *
-   *     Bit 31 is always zero (this is, `face_index` is always a positive
+   *     Bit 31 is always zero (that is, `face_index` is always a positive
    *     value).
    *
    *     [Since 2.9] Changing the design coordinates with
@@ -936,7 +1093,7 @@
    *
    *     [Since 2.6.1] Bits 16-30 hold the number of named instances
    *     available for the current face if we have a GX or OpenType variation
-   *     (sub)font.  Bit 31 is always zero (this is, `style_flags` is always
+   *     (sub)font.  Bit 31 is always zero (that is, `style_flags` is always
    *     a positive value).  Note that a variation font has always at least
    *     one named instance, namely the default instance.
    *
@@ -1002,7 +1159,7 @@
    *     Note that the bounding box might be off by (at least) one pixel for
    *     hinted fonts.  See @FT_Size_Metrics for further discussion.
    *
-   *     Note that the bounding box does not vary in OpenType variable fonts
+   *     Note that the bounding box does not vary in OpenType variation fonts
    *     and should only be used in relation to the default instance.
    *
    *   units_per_EM ::
@@ -1090,9 +1247,9 @@
 
     FT_Generic        generic;
 
-    /*# The following member variables (down to `underline_thickness`) */
-    /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size    */
-    /*# for bitmap fonts.                                              */
+    /* The following member variables (down to `underline_thickness`) */
+    /* are only relevant to scalable outlines; cf. @FT_Bitmap_Size    */
+    /* for bitmap fonts.                                              */
     FT_BBox           bbox;
 
     FT_UShort         units_per_EM;
@@ -1110,7 +1267,7 @@
     FT_Size           size;
     FT_CharMap        charmap;
 
-    /*@private begin */
+    /* private fields, internal to FreeType */
 
     FT_Driver         driver;
     FT_Memory         memory;
@@ -1123,8 +1280,6 @@
 
     FT_Face_Internal  internal;
 
-    /*@private end */
-
   } FT_FaceRec;
 
 
@@ -1207,13 +1362,13 @@
    *     successfully; in all other cases you get an
    *     `FT_Err_Invalid_Argument` error.
    *
-   *     Note that CID-keyed fonts that are in an SFNT wrapper (this is, all
+   *     Note that CID-keyed fonts that are in an SFNT wrapper (that is, all
    *     OpenType/CFF fonts) don't have this flag set since the glyphs are
    *     accessed in the normal way (using contiguous indices); the
    *     'CID-ness' isn't visible to the application.
    *
    *   FT_FACE_FLAG_TRICKY ::
-   *     The face is 'tricky', this is, it always needs the font format's
+   *     The face is 'tricky', that is, it always needs the font format's
    *     native hinting engine to get a reasonable result.  A typical example
    *     is the old Chinese font `mingli.ttf` (but not `mingliu.ttc`) that
    *     uses TrueType bytecode instructions to move and scale all of its
@@ -1235,8 +1390,8 @@
    *   FT_FACE_FLAG_VARIATION ::
    *     [Since 2.9] Set if the current face (or named instance) has been
    *     altered with @FT_Set_MM_Design_Coordinates,
-   *     @FT_Set_Var_Design_Coordinates, or @FT_Set_Var_Blend_Coordinates.
-   *     This flag is unset by a call to @FT_Set_Named_Instance.
+   *     @FT_Set_Var_Design_Coordinates, @FT_Set_Var_Blend_Coordinates, or
+   *     @FT_Set_MM_WeightVector to select a non-default instance.
    *
    *   FT_FACE_FLAG_SVG ::
    *     [Since 2.12] The face has an 'SVG~' OpenType table.
@@ -1274,6 +1429,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   font_testing_macros
+   *
+   */
+
+  /**************************************************************************
+   *
    * @macro:
    *   FT_HAS_HORIZONTAL
    *
@@ -1383,6 +1545,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   other_api_data
+   *
+   */
+
+  /**************************************************************************
+   *
    * @macro:
    *   FT_HAS_FAST_GLYPHS
    *
@@ -1395,6 +1564,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   font_testing_macros
+   *
+   */
+
+  /**************************************************************************
+   *
    * @macro:
    *   FT_HAS_GLYPH_NAMES
    *
@@ -1451,8 +1627,8 @@
    *
    * @description:
    *   A macro that returns true whenever a face object has been altered by
-   *   @FT_Set_MM_Design_Coordinates, @FT_Set_Var_Design_Coordinates, or
-   *   @FT_Set_Var_Blend_Coordinates.
+   *   @FT_Set_MM_Design_Coordinates, @FT_Set_Var_Design_Coordinates,
+   *   @FT_Set_Var_Blend_Coordinates, or @FT_Set_MM_WeightVector.
    *
    * @since:
    *   2.9
@@ -1630,6 +1806,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   face_creation
+   *
+   */
+
+  /**************************************************************************
+   *
    * @enum:
    *   FT_STYLE_FLAG_XXX
    *
@@ -1656,6 +1839,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   other_api_data
+   *
+   */
+
+  /**************************************************************************
+   *
    * @type:
    *   FT_Size_Internal
    *
@@ -1668,6 +1858,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   sizing_and_scaling
+   *
+   */
+
+  /**************************************************************************
+   *
    * @struct:
    *   FT_Size_Metrics
    *
@@ -1819,6 +2016,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   other_api_data
+   *
+   */
+
+  /**************************************************************************
+   *
    * @struct:
    *   FT_SubGlyph
    *
@@ -1850,6 +2054,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   glyph_retrieval
+   *
+   */
+
+  /**************************************************************************
+   *
    * @struct:
    *   FT_GlyphSlotRec
    *
@@ -2094,6 +2305,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   library_setup
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Init_FreeType
    *
@@ -2151,6 +2369,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   face_creation
+   *
+   */
+
+  /**************************************************************************
+   *
    * @enum:
    *   FT_OPEN_XXX
    *
@@ -2451,7 +2676,7 @@
    *   Each new face object created with this function also owns a default
    *   @FT_Size object, accessible as `face->size`.
    *
-   *   One @FT_Library instance can have multiple face objects, this is,
+   *   One @FT_Library instance can have multiple face objects, that is,
    *   @FT_Open_Face and its siblings can be called multiple times using the
    *   same `library` argument.
    *
@@ -2652,6 +2877,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   sizing_and_scaling
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Select_Size
    *
@@ -2679,7 +2911,7 @@
    *   silently uses outlines if there is no bitmap for a given glyph index.
    *
    *   For GX and OpenType variation fonts, a bitmap strike makes sense only
-   *   if the default instance is active (this is, no glyph variation takes
+   *   if the default instance is active (that is, no glyph variation takes
    *   place); otherwise, FreeType simply ignores bitmap strikes.  The same
    *   is true for all named instances that are different from the default
    *   instance.
@@ -2944,6 +3176,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   glyph_retrieval
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Load_Glyph
    *
@@ -2976,7 +3215,7 @@
    *   glyph may be transformed.  See @FT_Set_Transform for the details.
    *
    *   For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument` is returned
-   *   for invalid CID values (this is, for CID values that don't have a
+   *   for invalid CID values (that is, for CID values that don't have a
    *   corresponding glyph in the font).  See the discussion of the
    *   @FT_FACE_FLAG_CID_KEYED flag for more details.
    *
@@ -2992,6 +3231,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   character_mapping
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Load_Char
    *
@@ -3035,6 +3281,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   glyph_retrieval
+   *
+   */
+
+  /**************************************************************************
+   *
    * @enum:
    *   FT_LOAD_XXX
    *
@@ -3172,10 +3425,11 @@
    *
    *     [Since 2.12] If the glyph index maps to an entry in the face's
    *     'SVG~' table, load the associated SVG document from this table and
-   *     set the `format` field of @FT_GlyphSlotRec to @FT_GLYPH_FORMAT_SVG.
-   *     Note that FreeType itself can't render SVG documents; however, the
-   *     library provides hooks to seamlessly integrate an external renderer.
-   *     See sections @ot_svg_driver and @svg_fonts for more.
+   *     set the `format` field of @FT_GlyphSlotRec to @FT_GLYPH_FORMAT_SVG
+   *     ([since 2.13.1] provided @FT_LOAD_NO_SVG is not set).  Note that
+   *     FreeType itself can't render SVG documents; however, the library
+   *     provides hooks to seamlessly integrate an external renderer.  See
+   *     sections @ot_svg_driver and @svg_fonts for more.
    *
    *     [Since 2.10, experimental] If the glyph index maps to an entry in
    *     the face's 'COLR' table with a 'CPAL' palette table (as defined in
@@ -3189,6 +3443,9 @@
    *     @FT_Palette_Select instead of setting @FT_LOAD_COLOR for rendering
    *     so that the client application can handle blending by itself.
    *
+   *   FT_LOAD_NO_SVG ::
+   *     [Since 2.13.1] Ignore SVG glyph data when loading.
+   *
    *   FT_LOAD_COMPUTE_METRICS ::
    *     [Since 2.6.1] Compute glyph metrics from the glyph data, without the
    *     use of bundled metrics tables (for example, the 'hdmx' table in
@@ -3254,6 +3511,7 @@
 #define FT_LOAD_COLOR                        ( 1L << 20 )
 #define FT_LOAD_COMPUTE_METRICS              ( 1L << 21 )
 #define FT_LOAD_BITMAP_METRICS_ONLY          ( 1L << 22 )
+#define FT_LOAD_NO_SVG                       ( 1L << 24 )
 
   /* */
 
@@ -3374,6 +3632,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   sizing_and_scaling
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Set_Transform
    *
@@ -3449,6 +3714,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   glyph_retrieval
+   *
+   */
+
+  /**************************************************************************
+   *
    * @enum:
    *   FT_Render_Mode
    *
@@ -3843,6 +4115,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   character_mapping
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Select_Charmap
    *
@@ -4059,6 +4338,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   face_creation
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Face_Properties
    *
@@ -4157,6 +4443,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   information_retrieval
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Get_Name_Index
    *
@@ -4266,9 +4559,10 @@
    *
    *   [Since 2.9] Special PostScript names for named instances are only
    *   returned if the named instance is set with @FT_Set_Named_Instance (and
-   *   the font has corresponding entries in its 'fvar' table).  If
-   *   @FT_IS_VARIATION returns true, the algorithmically derived PostScript
-   *   name is provided, not looking up special entries for named instances.
+   *   the font has corresponding entries in its 'fvar' table or is the
+   *   default named instance).  If @FT_IS_VARIATION returns true, the
+   *   algorithmically derived PostScript name is provided, not looking up
+   *   special entries for named instances.
    */
   FT_EXPORT( const char* )
   FT_Get_Postscript_Name( FT_Face  face );
@@ -4900,32 +5194,10 @@
   /**************************************************************************
    *
    * @section:
-   *   version
-   *
-   * @title:
-   *   FreeType Version
-   *
-   * @abstract:
-   *   Functions and macros related to FreeType versions.
-   *
-   * @description:
-   *   Note that those functions and macros are of limited use because 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
+   *   library_setup
    *
    */
 
-
   /**************************************************************************
    *
    * @enum:
@@ -4950,7 +5222,7 @@
    */
 #define FREETYPE_MAJOR  2
 #define FREETYPE_MINOR  13
-#define FREETYPE_PATCH  0
+#define FREETYPE_PATCH  2
 
 
   /**************************************************************************
@@ -4994,6 +5266,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   other_api_data
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Face_CheckTrueTypePatents
    *
diff --git a/include/freetype/ftcache.h b/include/freetype/ftcache.h
index c768695..a2072e2 100644
--- a/include/freetype/ftcache.h
+++ b/include/freetype/ftcache.h
@@ -43,61 +43,61 @@
    *   objects, as well as caching information like character maps and glyph
    *   images while limiting their maximum memory usage.
    *
-   *   Note that all types and functions begin with the `FTC_` prefix.
+   *   Note that all types and functions begin with the `FTC_` prefix rather
+   *   than the usual `FT_` prefix in the rest of FreeType.
    *
-   *   The cache is highly portable and thus doesn't know anything about the
-   *   fonts installed on your system, or how to access them.  This implies
-   *   the following scheme:
+   *   The cache is highly portable and, thus, doesn't know anything about
+   *   the fonts installed on your system, or how to access them.  Therefore,
+   *   it requires the following.
    *
-   *   First, available or installed font faces are uniquely identified by
-   *   @FTC_FaceID values, provided to the cache by the client.  Note that
-   *   the cache only stores and compares these values, and doesn't try to
-   *   interpret them in any way.
+   *   * @FTC_FaceID, an arbitrary non-zero value that uniquely identifies
+   *     available or installed font faces, has to be provided to the
+   *     cache by the client.  Note that the cache only stores and compares
+   *     these values and doesn't try to interpret them in any way, but they
+   *     have to be persistent on the client side.
    *
-   *   Second, the cache calls, only when needed, a client-provided function
-   *   to convert an @FTC_FaceID into a new @FT_Face object.  The latter is
-   *   then completely managed by the cache, including its termination
-   *   through @FT_Done_Face.  To monitor termination of face objects, the
-   *   finalizer callback in the `generic` field of the @FT_Face object can
-   *   be used, which might also be used to store the @FTC_FaceID of the
-   *   face.
+   *   * @FTC_Face_Requester, a method to convert an @FTC_FaceID into a new
+   *     @FT_Face object when necessary, has to be provided to the cache by
+   *     the client.  The @FT_Face object is completely managed by the cache,
+   *     including its termination through @FT_Done_Face.  To monitor
+   *     termination of face objects, the finalizer callback in the `generic`
+   *     field of the @FT_Face object can be used, which might also be used
+   *     to store the @FTC_FaceID of the face.
    *
-   *   Clients are free to map face IDs to anything else.  The most simple
-   *   usage is to associate them to a (pathname,face_index) pair that is
-   *   used to call @FT_New_Face.  However, more complex schemes are also
-   *   possible.
+   *   Clients are free to map face IDs to anything useful.  The most simple
+   *   usage is, for example, to associate them to a `{pathname,face_index}`
+   *   pair that is then used by @FTC_Face_Requester to call @FT_New_Face.
+   *   However, more complex schemes are also possible.
    *
    *   Note that for the cache to work correctly, the face ID values must be
    *   **persistent**, which means that the contents they point to should not
    *   change at runtime, or that their value should not become invalid.
-   *
    *   If this is unavoidable (e.g., when a font is uninstalled at runtime),
-   *   you should call @FTC_Manager_RemoveFaceID as soon as possible, to let
+   *   you should call @FTC_Manager_RemoveFaceID as soon as possible to let
    *   the cache get rid of any references to the old @FTC_FaceID it may keep
    *   internally.  Failure to do so will lead to incorrect behaviour or even
-   *   crashes.
+   *   crashes in @FTC_Face_Requester.
    *
    *   To use the cache, start with calling @FTC_Manager_New to create a new
    *   @FTC_Manager object, which models a single cache instance.  You can
    *   then look up @FT_Face and @FT_Size objects with
-   *   @FTC_Manager_LookupFace and @FTC_Manager_LookupSize, respectively.
+   *   @FTC_Manager_LookupFace and @FTC_Manager_LookupSize, respectively, and
+   *   use them in any FreeType work stream.  You can also cache other
+   *   FreeType objects as follows.
    *
-   *   If you want to use the charmap caching, call @FTC_CMapCache_New, then
-   *   later use @FTC_CMapCache_Lookup to perform the equivalent of
-   *   @FT_Get_Char_Index, only much faster.
+   *   * If you want to use the charmap caching, call @FTC_CMapCache_New,
+   *     then later use @FTC_CMapCache_Lookup to perform the equivalent of
+   *     @FT_Get_Char_Index, only much faster.
    *
-   *   If you want to use the @FT_Glyph caching, call @FTC_ImageCache_New,
-   *   then later use @FTC_ImageCache_Lookup to retrieve the corresponding
-   *   @FT_Glyph objects from the cache.
+   *   * If you want to use the @FT_Glyph caching, call @FTC_ImageCache_New,
+   *     then later use @FTC_ImageCache_Lookup to retrieve the corresponding
+   *     @FT_Glyph objects from the cache.
    *
-   *   If you need lots of small bitmaps, it is much more memory efficient to
-   *   call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup.  This
-   *   returns @FTC_SBitRec structures, which are used to store small bitmaps
-   *   directly.  (A small bitmap is one whose metrics and dimensions all fit
-   *   into 8-bit integers).
-   *
-   *   We hope to also provide a kerning cache in the near future.
-   *
+   *   * If you need lots of small bitmaps, it is much more memory-efficient
+   *     to call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup.  This
+   *     returns @FTC_SBitRec structures, which are used to store small
+   *     bitmaps directly.  (A small bitmap is one whose metrics and
+   *     dimensions all fit into 8-bit integers).
    *
    * @order:
    *   FTC_Manager
diff --git a/include/freetype/ftchapters.h b/include/freetype/ftchapters.h
index 6a9733a..7566fbd 100644
--- a/include/freetype/ftchapters.h
+++ b/include/freetype/ftchapters.h
@@ -31,9 +31,28 @@
    *   Core API
    *
    * @sections:
-   *   version
    *   basic_types
-   *   base_interface
+   *   library_setup
+   *   face_creation
+   *   font_testing_macros
+   *   sizing_and_scaling
+   *   glyph_retrieval
+   *   character_mapping
+   *   information_retrieval
+   *   other_api_data
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @chapter:
+   *   extended_api
+   *
+   * @title:
+   *   Extended API
+   *
+   * @sections:
    *   glyph_variants
    *   color_management
    *   layer_management
diff --git a/include/freetype/ftdriver.h b/include/freetype/ftdriver.h
index f90946f..7af7465 100644
--- a/include/freetype/ftdriver.h
+++ b/include/freetype/ftdriver.h
@@ -134,7 +134,7 @@
    *   each being rounded to the nearest pixel edge, taking care of overshoot
    *   suppression at small sizes, stem darkening, and scaling.
    *
-   *   Hstems (this is, hint values defined in the font to help align
+   *   Hstems (that is, hint values defined in the font to help align
    *   horizontal features) that fall within a blue zone are said to be
    *   'captured' and are aligned to that zone.  Uncaptured stems are moved
    *   in one of four ways, top edge up or down, bottom edge up or down.
@@ -446,7 +446,7 @@
    *   at smaller sizes.
    *
    *   For the auto-hinter, stem-darkening is experimental currently and thus
-   *   switched off by default (this is, `no-stem-darkening` is set to TRUE
+   *   switched off by default (that is, `no-stem-darkening` is set to TRUE
    *   by default).  Total consistency with the CFF driver is not achieved
    *   right now because the emboldening method differs and glyphs must be
    *   scaled down on the Y-axis to keep outline points inside their
@@ -651,11 +651,8 @@
    *     Windows~98; only grayscale and B/W rasterizing is supported.
    *
    *   TT_INTERPRETER_VERSION_38 ::
-   *     Version~38 corresponds to MS rasterizer v.1.9; it is roughly
-   *     equivalent to the hinting provided by DirectWrite ClearType (as can
-   *     be found, for example, in the Internet Explorer~9 running on
-   *     Windows~7).  It is used in FreeType to select the 'Infinality'
-   *     subpixel hinting code.  The code may be removed in a future version.
+   *     Version~38 is the same Version~40. The original 'Infinality' code is
+   *     no longer available.
    *
    *   TT_INTERPRETER_VERSION_40 ::
    *     Version~40 corresponds to MS rasterizer v.2.1; it is roughly
diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h
index 2e8e673..6baa812 100644
--- a/include/freetype/ftimage.h
+++ b/include/freetype/ftimage.h
@@ -19,7 +19,7 @@
   /**************************************************************************
    *
    * Note: A 'raster' is simply a scan-line converter, used to render
-   *       FT_Outlines into FT_Bitmaps.
+   *       `FT_Outline`s into `FT_Bitmap`s.
    *
    */
 
@@ -256,6 +256,12 @@
    *   palette ::
    *     A typeless pointer to the bitmap palette; this field is intended for
    *     paletted pixel modes.  Not used currently.
+   *
+   * @note:
+   *   `width` and `rows` refer to the *physical* size of the bitmap, not the
+   *   *logical* one.  For example, if @FT_Pixel_Mode is set to
+   *   `FT_PIXEL_MODE_LCD`, the logical width is a just a third of the
+   *   physical one.
    */
   typedef struct  FT_Bitmap_
   {
@@ -856,7 +862,7 @@
    *   @FT_SpanFunc that takes the y~coordinate of the span as a parameter.
    *
    *   The anti-aliased rasterizer produces coverage values from 0 to 255,
-   *   this is, from completely transparent to completely opaque.
+   *   that is, from completely transparent to completely opaque.
    */
   typedef struct  FT_Span_
   {
diff --git a/include/freetype/ftlogging.h b/include/freetype/ftlogging.h
index 2246dc8..53b8b89 100644
--- a/include/freetype/ftlogging.h
+++ b/include/freetype/ftlogging.h
@@ -62,7 +62,7 @@
    *   component.
    *
    *   ```
-   *   FT_Trace_Set_Level( "any:7 memory:0 );
+   *   FT_Trace_Set_Level( "any:7 memory:0" );
    *   ```
    *
    * @note:
diff --git a/include/freetype/ftmm.h b/include/freetype/ftmm.h
index e381ef3..d145128 100644
--- a/include/freetype/ftmm.h
+++ b/include/freetype/ftmm.h
@@ -153,7 +153,7 @@
    * @note:
    *   The fields `minimum`, `def`, and `maximum` are 16.16 fractional values
    *   for TrueType GX and OpenType variation fonts.  For Adobe MM fonts, the
-   *   values are integers.
+   *   values are whole numbers (i.e., the fractional part is zero).
    */
   typedef struct  FT_Var_Axis_
   {
@@ -399,8 +399,8 @@
    *
    * @note:
    *   The design coordinates are 16.16 fractional values for TrueType GX and
-   *   OpenType variation fonts.  For Adobe MM fonts, the values are
-   *   integers.
+   *   OpenType variation fonts.  For Adobe MM fonts, the values are supposed
+   *   to be whole numbers (i.e., the fractional part is zero).
    *
    *   [Since 2.8.1] To reset all axes to the default values, call the
    *   function with `num_coords` set to zero and `coords` set to `NULL`.
@@ -446,8 +446,8 @@
    *
    * @note:
    *   The design coordinates are 16.16 fractional values for TrueType GX and
-   *   OpenType variation fonts.  For Adobe MM fonts, the values are
-   *   integers.
+   *   OpenType variation fonts.  For Adobe MM fonts, the values are whole
+   *   numbers (i.e., the fractional part is zero).
    *
    * @since:
    *   2.7.1
@@ -602,10 +602,12 @@
    *
    * @note:
    *   Adobe Multiple Master fonts limit the number of designs, and thus the
-   *   length of the weight vector to~16.
+   *   length of the weight vector to 16~elements.
    *
-   *   If `len` is zero and `weightvector` is `NULL`, the weight vector array
-   *   is reset to the default values.
+   *   If `len` is larger than zero, this function sets the
+   *   @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags` field (i.e.,
+   *   @FT_IS_VARIATION will return true).  If `len` is zero, this bit flag
+   *   is unset and the weight vector array is reset to the default values.
    *
    *   The Adobe documentation also states that the values in the
    *   WeightVector array must total 1.0 +/-~0.001.  In practice this does
@@ -753,6 +755,45 @@
   FT_Set_Named_Instance( FT_Face  face,
                          FT_UInt  instance_index );
 
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Get_Default_Named_Instance
+   *
+   * @description:
+   *   Retrieve the index of the default named instance, to be used with
+   *   @FT_Set_Named_Instance.
+   *
+   *   The default instance of a variation font is that instance for which
+   *   the nth axis coordinate is equal to `axis[n].def` (as specified in the
+   *   @FT_MM_Var structure), with~n covering all axes.
+   *
+   *   FreeType synthesizes a named instance for the default instance if the
+   *   font does not contain such an entry.
+   *
+   * @input:
+   *   face ::
+   *     A handle to the source face.
+   *
+   * @output:
+   *   instance_index ::
+   *     The index of the default named instance.
+   *
+   * @return:
+   *   FreeType error code.  0~means success.
+   *
+   * @note:
+   *   For Adobe MM fonts (which don't have named instances) this function
+   *   always returns zero for `instance_index`.
+   *
+   * @since:
+   *   2.13.1
+   */
+  FT_EXPORT( FT_Error )
+  FT_Get_Default_Named_Instance( FT_Face   face,
+                                 FT_UInt  *instance_index );
+
   /* */
 
 
diff --git a/include/freetype/ftoutln.h b/include/freetype/ftoutln.h
index 54434b2..f9329ca 100644
--- a/include/freetype/ftoutln.h
+++ b/include/freetype/ftoutln.h
@@ -118,7 +118,7 @@
    *   attachement.
    *
    *   Similarly, the function returns success for an empty outline also
-   *   (doing nothing, this is, not calling any emitter); if necessary, you
+   *   (doing nothing, that is, not calling any emitter); if necessary, you
    *   should filter this out, too.
    */
   FT_EXPORT( FT_Error )
diff --git a/include/freetype/ftrender.h b/include/freetype/ftrender.h
index a8576da..0b6fad3 100644
--- a/include/freetype/ftrender.h
+++ b/include/freetype/ftrender.h
@@ -158,7 +158,7 @@
     FT_Renderer_GetCBoxFunc    get_glyph_cbox;
     FT_Renderer_SetModeFunc    set_mode;
 
-    FT_Raster_Funcs*           raster_class;
+    const FT_Raster_Funcs*     raster_class;
 
   } FT_Renderer_Class;
 
diff --git a/include/freetype/ftsynth.h b/include/freetype/ftsynth.h
index 5d19697..af90967 100644
--- a/include/freetype/ftsynth.h
+++ b/include/freetype/ftsynth.h
@@ -68,6 +68,18 @@
   FT_EXPORT( void )
   FT_GlyphSlot_Embolden( FT_GlyphSlot  slot );
 
+  /* Precisely adjust the glyph weight either horizontally or vertically.  */
+  /* The `xdelta` and `ydelta` values are fractions of the face Em size    */
+  /* (in fixed-point format).  Considering that a regular face would have  */
+  /* stem widths on the order of 0.1 Em, a delta of 0.05 (0x0CCC) should   */
+  /* be very noticeable.  To increase or decrease the weight, use positive */
+  /* or negative values, respectively.                                     */
+  FT_EXPORT( void )
+  FT_GlyphSlot_AdjustWeight( FT_GlyphSlot  slot,
+                             FT_Fixed      xdelta,
+                             FT_Fixed      ydelta );
+
+
   /* Slant an outline glyph to the right by about 12 degrees.              */
   FT_EXPORT( void )
   FT_GlyphSlot_Oblique( FT_GlyphSlot  slot );
diff --git a/include/freetype/ftsystem.h b/include/freetype/ftsystem.h
index a995b07..3a08f49 100644
--- a/include/freetype/ftsystem.h
+++ b/include/freetype/ftsystem.h
@@ -229,8 +229,7 @@
    *     A handle to the source stream.
    *
    *   offset ::
-   *     The offset from the start of the stream to seek to if this is a seek
-   *     operation (see note).
+   *     The offset from the start of the stream to seek to.
    *
    *   buffer ::
    *     The address of the read buffer.
@@ -239,16 +238,9 @@
    *     The number of bytes to read from the stream.
    *
    * @return:
-   *   The number of bytes effectively read by the stream.
-   *
-   * @note:
-   *   This function performs a seek *or* a read operation depending on the
-   *   argument values.  If `count` is zero, the operation is a seek to
-   *   `offset` bytes.  If `count` is >~0, the operation is a read of `count`
-   *   bytes from the current position in the stream, and the `offset` value
-   *   should be ignored.
-   *
-   *   For seek operations, a non-zero return value indicates an error.
+   *   If count >~0, return the number of bytes effectively read by the
+   *   stream (after seeking to `offset`).  If count ==~0, return the status
+   *   of the seek operation (non-zero indicates an error).
    *
    */
   typedef unsigned long
diff --git a/include/freetype/internal/compiler-macros.h b/include/freetype/internal/compiler-macros.h
index 7883317..6f67650 100644
--- a/include/freetype/internal/compiler-macros.h
+++ b/include/freetype/internal/compiler-macros.h
@@ -41,8 +41,11 @@
 #  if ( defined( __STDC_VERSION__ ) && __STDC_VERSION__ > 201710L ) || \
       ( defined( __cplusplus ) && __cplusplus > 201402L )
 #    define FALL_THROUGH  [[__fallthrough__]]
-#  elif ( defined( __GNUC__ ) && __GNUC__ >= 7 )          || \
-        ( defined( __clang__ ) && __clang_major__ >= 10 )
+#  elif ( defined( __GNUC__ ) && __GNUC__ >= 7 )       || \
+        ( defined( __clang__ )                      &&    \
+          ( defined( __apple_build_version__ )            \
+              ? __apple_build_version__ >= 12000000       \
+              : __clang_major__ >= 10 ) )
 #    define FALL_THROUGH  __attribute__(( __fallthrough__ ))
 #  else
 #    define FALL_THROUGH  ( (void)0 )
diff --git a/include/freetype/internal/ftcalc.h b/include/freetype/internal/ftcalc.h
index d1baa39..d9aea23 100644
--- a/include/freetype/internal/ftcalc.h
+++ b/include/freetype/internal/ftcalc.h
@@ -332,9 +332,9 @@
    * Based on geometric considerations we use the following inequality to
    * identify a degenerate matrix.
    *
-   *   50 * abs(xx*yy - xy*yx) < xx^2 + xy^2 + yx^2 + yy^2
+   *   32 * abs(xx*yy - xy*yx) < xx^2 + xy^2 + yx^2 + yy^2
    *
-   * Value 50 is heuristic.
+   * Value 32 is heuristic.
    */
   FT_BASE( FT_Bool )
   FT_Matrix_Check( const FT_Matrix*  matrix );
diff --git a/include/freetype/internal/ftdrv.h b/include/freetype/internal/ftdrv.h
index f78912c..9001c07 100644
--- a/include/freetype/internal/ftdrv.h
+++ b/include/freetype/internal/ftdrv.h
@@ -157,6 +157,7 @@
    *     A handle to a function used to select a new fixed size.  It is used
    *     only if @FT_FACE_FLAG_FIXED_SIZES is set.  Can be set to 0 if the
    *     scaling done in the base layer suffices.
+   *
    * @note:
    *   Most function pointers, with the exception of `load_glyph`, can be set
    *   to 0 to indicate a default behaviour.
diff --git a/include/freetype/internal/ftmmtypes.h b/include/freetype/internal/ftmmtypes.h
index b7c66c3..c4b21d6 100644
--- a/include/freetype/internal/ftmmtypes.h
+++ b/include/freetype/internal/ftmmtypes.h
@@ -28,13 +28,19 @@
 
   typedef struct  GX_ItemVarDataRec_
   {
-    FT_UInt            itemCount;       /* number of delta sets per item    */
-    FT_UInt            regionIdxCount;  /* number of region indices         */
-    FT_UInt*           regionIndices;   /* array of `regionCount' indices;  */
-                                        /* these index `varRegionList'      */
-    FT_ItemVarDelta*   deltaSet;        /* array of `itemCount' deltas      */
-                                        /* use `innerIndex' for this array  */
-
+    FT_UInt            itemCount;      /* Number of delta sets per item.   */
+    FT_UInt            regionIdxCount; /* Number of region indices.        */
+    FT_UInt*           regionIndices;  /* Array of `regionCount` indices;  */
+                                       /* these index `varRegionList`.     */
+    FT_Byte*           deltaSet;       /* Array of `itemCount` deltas;     */
+                                       /* use `innerIndex` for this array. */
+    FT_UShort          wordDeltaCount; /* Number of the first 32-bit ints  */
+                                       /* or 16-bit ints of `deltaSet`     */
+                                       /* depending on `longWords`.        */
+    FT_Bool            longWords;      /* If true, `deltaSet` is a 32-bit  */
+                                       /* array followed by a 16-bit       */
+                                       /* array, otherwise a 16-bit array  */
+                                       /* followed by an 8-bit array.      */
   } GX_ItemVarDataRec, *GX_ItemVarData;
 
 
diff --git a/include/freetype/internal/services/svmm.h b/include/freetype/internal/services/svmm.h
index d942042..7e76ab8 100644
--- a/include/freetype/internal/services/svmm.h
+++ b/include/freetype/internal/services/svmm.h
@@ -60,9 +60,9 @@
   /* use return value -1 to indicate that the new coordinates  */
   /* are equal to the current ones; no changes are thus needed */
   typedef FT_Error
-  (*FT_Set_MM_Blend_Func)( FT_Face   face,
-                           FT_UInt   num_coords,
-                           FT_Long*  coords );
+  (*FT_Set_MM_Blend_Func)( FT_Face    face,
+                           FT_UInt    num_coords,
+                           FT_Fixed*  coords );
 
   typedef FT_Error
   (*FT_Get_Var_Design_Func)( FT_Face    face,
@@ -70,13 +70,17 @@
                              FT_Fixed*  coords );
 
   typedef FT_Error
-  (*FT_Set_Instance_Func)( FT_Face  face,
-                           FT_UInt  instance_index );
+  (*FT_Set_Named_Instance_Func)( FT_Face  face,
+                                 FT_UInt  instance_index );
 
   typedef FT_Error
-  (*FT_Get_MM_Blend_Func)( FT_Face   face,
-                           FT_UInt   num_coords,
-                           FT_Long*  coords );
+  (*FT_Get_Default_Named_Instance_Func)( FT_Face   face,
+                                         FT_UInt  *instance_index );
+
+  typedef FT_Error
+  (*FT_Get_MM_Blend_Func)( FT_Face    face,
+                           FT_UInt    num_coords,
+                           FT_Fixed*  coords );
 
   typedef FT_Error
   (*FT_Get_Var_Blend_Func)( FT_Face      face,
@@ -86,7 +90,7 @@
                             FT_MM_Var*  *mm_var );
 
   typedef void
-  (*FT_Done_Blend_Func)( FT_Face );
+  (*FT_Done_Blend_Func)( FT_Face  face );
 
   typedef FT_Error
   (*FT_Set_MM_WeightVector_Func)( FT_Face    face,
@@ -98,6 +102,9 @@
                                   FT_UInt*   len,
                                   FT_Fixed*  weight_vector );
 
+  typedef void
+  (*FT_Construct_PS_Name_Func)( FT_Face  face );
+
   typedef FT_Error
   (*FT_Var_Load_Delta_Set_Idx_Map_Func)( FT_Face            face,
                                          FT_ULong           offset,
@@ -134,11 +141,13 @@
     FT_Get_MM_Var_Func                    get_mm_var;
     FT_Set_Var_Design_Func                set_var_design;
     FT_Get_Var_Design_Func                get_var_design;
-    FT_Set_Instance_Func                  set_instance;
+    FT_Set_Named_Instance_Func            set_named_instance;
+    FT_Get_Default_Named_Instance_Func    get_default_named_instance;
     FT_Set_MM_WeightVector_Func           set_mm_weightvector;
     FT_Get_MM_WeightVector_Func           get_mm_weightvector;
 
     /* for internal use; only needed for code sharing between modules */
+    FT_Construct_PS_Name_Func             construct_ps_name;
     FT_Var_Load_Delta_Set_Idx_Map_Func    load_delta_set_idx_map;
     FT_Var_Load_Item_Var_Store_Func       load_item_var_store;
     FT_Var_Get_Item_Delta_Func            get_item_delta;
@@ -149,43 +158,49 @@
   };
 
 
-#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_,                  \
-                                           get_mm_,                 \
-                                           set_mm_design_,          \
-                                           set_mm_blend_,           \
-                                           get_mm_blend_,           \
-                                           get_mm_var_,             \
-                                           set_var_design_,         \
-                                           get_var_design_,         \
-                                           set_instance_,           \
-                                           set_weightvector_,       \
-                                           get_weightvector_,       \
-                                           load_delta_set_idx_map_, \
-                                           load_item_var_store_,    \
-                                           get_item_delta_,         \
-                                           done_item_var_store_,    \
-                                           done_delta_set_idx_map_, \
-                                           get_var_blend_,          \
-                                           done_blend_ )            \
-  static const FT_Service_MultiMastersRec  class_ =                 \
-  {                                                                 \
-    get_mm_,                                                        \
-    set_mm_design_,                                                 \
-    set_mm_blend_,                                                  \
-    get_mm_blend_,                                                  \
-    get_mm_var_,                                                    \
-    set_var_design_,                                                \
-    get_var_design_,                                                \
-    set_instance_,                                                  \
-    set_weightvector_,                                              \
-    get_weightvector_,                                              \
-    load_delta_set_idx_map_,                                        \
-    load_item_var_store_,                                           \
-    get_item_delta_,                                                \
-    done_item_var_store_,                                           \
-    done_delta_set_idx_map_,                                        \
-    get_var_blend_,                                                 \
-    done_blend_                                                     \
+#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_,                      \
+                                           get_mm_,                     \
+                                           set_mm_design_,              \
+                                           set_mm_blend_,               \
+                                           get_mm_blend_,               \
+                                           get_mm_var_,                 \
+                                           set_var_design_,             \
+                                           get_var_design_,             \
+                                           set_named_instance_,         \
+                                           get_default_named_instance_, \
+                                           set_mm_weightvector_,        \
+                                           get_mm_weightvector_,        \
+                                                                        \
+                                           construct_ps_name_,          \
+                                           load_delta_set_idx_map_,     \
+                                           load_item_var_store_,        \
+                                           get_item_delta_,             \
+                                           done_item_var_store_,        \
+                                           done_delta_set_idx_map_,     \
+                                           get_var_blend_,              \
+                                           done_blend_ )                \
+  static const FT_Service_MultiMastersRec  class_ =                     \
+  {                                                                     \
+    get_mm_,                                                            \
+    set_mm_design_,                                                     \
+    set_mm_blend_,                                                      \
+    get_mm_blend_,                                                      \
+    get_mm_var_,                                                        \
+    set_var_design_,                                                    \
+    get_var_design_,                                                    \
+    set_named_instance_,                                                \
+    get_default_named_instance_,                                        \
+    set_mm_weightvector_,                                               \
+    get_mm_weightvector_,                                               \
+                                                                        \
+    construct_ps_name_,                                                 \
+    load_delta_set_idx_map_,                                            \
+    load_item_var_store_,                                               \
+    get_item_delta_,                                                    \
+    done_item_var_store_,                                               \
+    done_delta_set_idx_map_,                                            \
+    get_var_blend_,                                                     \
+    done_blend_                                                         \
   };
 
   /* */
diff --git a/include/freetype/internal/services/svpscmap.h b/include/freetype/internal/services/svpscmap.h
index fd99d85..6e599f3 100644
--- a/include/freetype/internal/services/svpscmap.h
+++ b/include/freetype/internal/services/svpscmap.h
@@ -97,7 +97,7 @@
   (*PS_Unicodes_CharIndexFunc)( PS_Unicodes  unicodes,
                                 FT_UInt32    unicode );
 
-  typedef FT_UInt32
+  typedef FT_UInt
   (*PS_Unicodes_CharNextFunc)( PS_Unicodes  unicodes,
                                FT_UInt32   *unicode );
 
diff --git a/include/freetype/internal/t1types.h b/include/freetype/internal/t1types.h
index 5a105c5..b9c9439 100644
--- a/include/freetype/internal/t1types.h
+++ b/include/freetype/internal/t1types.h
@@ -201,30 +201,30 @@
 
   typedef struct  T1_FaceRec_
   {
-    FT_FaceRec      root;
-    T1_FontRec      type1;
-    const void*     psnames;
-    const void*     psaux;
-    const void*     afm_data;
-    FT_CharMapRec   charmaprecs[2];
-    FT_CharMap      charmaps[2];
+    FT_FaceRec     root;
+    T1_FontRec     type1;
+    const void*    psnames;
+    const void*    psaux;
+    const void*    afm_data;
+    FT_CharMapRec  charmaprecs[2];
+    FT_CharMap     charmaps[2];
 
     /* support for Multiple Masters fonts */
-    PS_Blend        blend;
+    PS_Blend       blend;
 
     /* undocumented, optional: indices of subroutines that express      */
     /* the NormalizeDesignVector and the ConvertDesignVector procedure, */
     /* respectively, as Type 2 charstrings; -1 if keywords not present  */
-    FT_Int           ndv_idx;
-    FT_Int           cdv_idx;
+    FT_Int         ndv_idx;
+    FT_Int         cdv_idx;
 
     /* undocumented, optional: has the same meaning as len_buildchar */
     /* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25    */
-    FT_UInt          len_buildchar;
-    FT_Long*         buildchar;
+    FT_UInt        len_buildchar;
+    FT_Long*       buildchar;
 
     /* since version 2.1 - interface to PostScript hinter */
-    const void*     pshinter;
+    const void*    pshinter;
 
   } T1_FaceRec;
 
diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h
index 785073e..b9788c7 100644
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -779,13 +779,15 @@
   /**************************************************************************
    *
    * @struct:
-   *   TT_Post_20Rec
+   *   TT_Post_NamesRec
    *
    * @description:
-   *   Postscript names sub-table, format 2.0.  Stores the PS name of each
-   *   glyph in the font face.
+   *   Postscript names table, either format 2.0 or 2.5.
    *
    * @fields:
+   *   loaded ::
+   *     A flag to indicate whether the PS names are loaded.
+   *
    *   num_glyphs ::
    *     The number of named glyphs in the table.
    *
@@ -798,68 +800,13 @@
    *   glyph_names ::
    *     The PS names not in Mac Encoding.
    */
-  typedef struct  TT_Post_20Rec_
+  typedef struct  TT_Post_NamesRec_
   {
+    FT_Bool     loaded;
     FT_UShort   num_glyphs;
     FT_UShort   num_names;
     FT_UShort*  glyph_indices;
-    FT_Char**   glyph_names;
-
-  } TT_Post_20Rec, *TT_Post_20;
-
-
-  /**************************************************************************
-   *
-   * @struct:
-   *   TT_Post_25Rec
-   *
-   * @description:
-   *   Postscript names sub-table, format 2.5.  Stores the PS name of each
-   *   glyph in the font face.
-   *
-   * @fields:
-   *   num_glyphs ::
-   *     The number of glyphs in the table.
-   *
-   *   offsets ::
-   *     An array of signed offsets in a normal Mac Postscript name encoding.
-   */
-  typedef struct  TT_Post_25_
-  {
-    FT_UShort  num_glyphs;
-    FT_Char*   offsets;
-
-  } TT_Post_25Rec, *TT_Post_25;
-
-
-  /**************************************************************************
-   *
-   * @struct:
-   *   TT_Post_NamesRec
-   *
-   * @description:
-   *   Postscript names table, either format 2.0 or 2.5.
-   *
-   * @fields:
-   *   loaded ::
-   *     A flag to indicate whether the PS names are loaded.
-   *
-   *   format_20 ::
-   *     The sub-table used for format 2.0.
-   *
-   *   format_25 ::
-   *     The sub-table used for format 2.5.
-   */
-  typedef struct  TT_Post_NamesRec_
-  {
-    FT_Bool  loaded;
-
-    union
-    {
-      TT_Post_20Rec  format_20;
-      TT_Post_25Rec  format_25;
-
-    } names;
+    FT_Byte**   glyph_names;
 
   } TT_Post_NamesRec, *TT_Post_Names;
 
@@ -1253,12 +1200,16 @@
    *   mm ::
    *     A pointer to the Multiple Masters service.
    *
-   *   var ::
-   *     A pointer to the Metrics Variations service.
+   *   tt_var ::
+   *     A pointer to the Metrics Variations service for the "truetype"
+   *     driver.
    *
-   *   hdmx ::
-   *     The face's horizontal device metrics ('hdmx' table).  This table is
-   *     optional in TrueType/OpenType fonts.
+   *   face_var ::
+   *     A pointer to the Metrics Variations service for this `TT_Face`'s
+   *     driver.
+   *
+   *   psaux ::
+   *     A pointer to the PostScript Auxiliary service.
    *
    *   gasp ::
    *     The grid-fitting and scaling properties table ('gasp').  This table
@@ -1364,6 +1315,12 @@
    *   var_postscript_prefix_len ::
    *     The length of the `var_postscript_prefix` string.
    *
+   *   var_default_named_instance ::
+   *     The index of the default named instance.
+   *
+   *   non_var_style_name ::
+   *     The non-variation style name, used as a backup.
+   *
    *   horz_metrics_size ::
    *     The size of the 'hmtx' table.
    *
@@ -1410,14 +1367,6 @@
    *     A mapping between the strike indices exposed by the API and the
    *     indices used in the font's sbit table.
    *
-   *   cpal ::
-   *     A pointer to data related to the 'CPAL' table.  `NULL` if the table
-   *     is not available.
-   *
-   *   colr ::
-   *     A pointer to data related to the 'COLR' table.  `NULL` if the table
-   *     is not available.
-   *
    *   kern_table ::
    *     A pointer to the 'kern' table.
    *
@@ -1445,19 +1394,23 @@
    *   vert_metrics_offset ::
    *     The file offset of the 'vmtx' table.
    *
-   *   sph_found_func_flags ::
-   *     Flags identifying special bytecode functions (used by the v38
-   *     implementation of the bytecode interpreter).
-   *
-   *   sph_compatibility_mode ::
-   *     This flag is set if we are in ClearType backward compatibility mode
-   *     (used by the v38 implementation of the bytecode interpreter).
-   *
    *   ebdt_start ::
    *     The file offset of the sbit data table (CBDT, bdat, etc.).
    *
    *   ebdt_size ::
    *     The size of the sbit data table.
+   *
+   *   cpal ::
+   *     A pointer to data related to the 'CPAL' table.  `NULL` if the table
+   *     is not available.
+   *
+   *   colr ::
+   *     A pointer to data related to the 'COLR' table.  `NULL` if the table
+   *     is not available.
+   *
+   *   svg ::
+   *     A pointer to data related to the 'SVG' table.  `NULL` if the table
+   *     is not available.
    */
   typedef struct  TT_FaceRec_
   {
@@ -1515,7 +1468,7 @@
     /* a typeless pointer to the FT_Service_MetricsVariationsRec table */
     /* used to handle the HVAR, VVAR, and MVAR OpenType tables by this */
     /* TT_Face's driver                                                */
-    void*                 face_var;
+    void*                 face_var;             /* since 2.13.1 */
 #endif
 
     /* a typeless pointer to the PostScript Aux service */
@@ -1597,6 +1550,9 @@
     const char*           var_postscript_prefix;     /* since 2.7.2 */
     FT_UInt               var_postscript_prefix_len; /* since 2.7.2 */
 
+    FT_UInt               var_default_named_instance;  /* since 2.13.1 */
+
+    const char*           non_var_style_name;  /* since 2.13.1 */
 #endif
 
     /* since version 2.2 */
@@ -1633,13 +1589,6 @@
     FT_ULong              horz_metrics_offset;
     FT_ULong              vert_metrics_offset;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    /* since 2.4.12 */
-    FT_ULong              sph_found_func_flags; /* special functions found */
-                                                /* for this face           */
-    FT_Bool               sph_compatibility_mode;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
     /* since 2.7 */
     FT_ULong              ebdt_start;  /* either `CBDT', `EBDT', or `bdat' */
diff --git a/src/autofit/afblue.dat b/src/autofit/afblue.dat
index b7efe8b..8299baa 100644
--- a/src/autofit/afblue.dat
+++ b/src/autofit/afblue.dat
@@ -89,7 +89,7 @@
     "ت ث ط ظ ك"
   // We don't necessarily have access to medial forms via Unicode in case
   // Arabic presentational forms are missing.  The only character that is
-  // guaranteed to have the same vertical position with joining (this is,
+  // guaranteed to have the same vertical position with joining (that is,
   // non-isolated) forms is U+0640, ARABIC TATWEEL, which must join both
   // round and flat curves.
   AF_BLUE_STRING_ARABIC_JOIN
diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c
index 5daefff..f414289 100644
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -417,16 +417,14 @@
 
         {
           FT_Int  nn;
-          FT_Int  first = 0;
-          FT_Int  last  = -1;
+          FT_Int  pp, first, last;
 
 
-          for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ )
+          last = -1;
+          for ( nn = 0; nn < outline.n_contours; nn++ )
           {
-            FT_Int  pp;
-
-
-            last = outline.contours[nn];
+            first = last + 1;
+            last  = outline.contours[nn];
 
             /* Avoid single-point contours since they are never rasterized. */
             /* In some fonts, they correspond to mark attachment points     */
@@ -569,8 +567,8 @@
   af_cjk_metrics_check_digits( AF_CJKMetrics  metrics,
                                FT_Face        face )
   {
-    FT_Bool   started = 0, same_width = 1;
-    FT_Fixed  advance = 0, old_advance = 0;
+    FT_Bool  started = 0, same_width = 1;
+    FT_Long  advance = 0, old_advance = 0;
 
     /* If HarfBuzz is not available, we need a pointer to a single */
     /* unsigned long value.                                        */
@@ -635,10 +633,11 @@
   /* Initialize global metrics. */
 
   FT_LOCAL_DEF( FT_Error )
-  af_cjk_metrics_init( AF_CJKMetrics  metrics,
-                       FT_Face        face )
+  af_cjk_metrics_init( AF_StyleMetrics  metrics_,  /* AF_CJKMetrics */
+                       FT_Face          face )
   {
-    FT_CharMap  oldmap = face->charmap;
+    AF_CJKMetrics  metrics = (AF_CJKMetrics)metrics_;
+    FT_CharMap     oldmap  = face->charmap;
 
 
     metrics->units_per_em = face->units_per_EM;
@@ -756,9 +755,12 @@
   /* Scale global values in both directions. */
 
   FT_LOCAL_DEF( void )
-  af_cjk_metrics_scale( AF_CJKMetrics  metrics,
-                        AF_Scaler      scaler )
+  af_cjk_metrics_scale( AF_StyleMetrics  metrics_,   /* AF_CJKMetrics */
+                        AF_Scaler        scaler )
   {
+    AF_CJKMetrics  metrics = (AF_CJKMetrics)metrics_;
+
+
     /* we copy the whole structure since the x and y scaling values */
     /* are not modified, contrary to e.g. the `latin' auto-hinter   */
     metrics->root.scaler = *scaler;
@@ -771,11 +773,14 @@
   /* Extract standard_width from writing system/script specific */
   /* metrics class.                                             */
 
-  FT_LOCAL_DEF( void )
-  af_cjk_get_standard_widths( AF_CJKMetrics  metrics,
-                              FT_Pos*        stdHW,
-                              FT_Pos*        stdVW )
+  FT_CALLBACK_DEF( void )
+  af_cjk_get_standard_widths( AF_StyleMetrics  metrics_,  /* AF_CJKMetrics */
+                              FT_Pos*          stdHW,
+                              FT_Pos*          stdVW )
   {
+    AF_CJKMetrics  metrics = (AF_CJKMetrics)metrics_;
+
+
     if ( stdHW )
       *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width;
 
@@ -1376,9 +1381,10 @@
   /* Initalize hinting engine. */
 
   FT_LOCAL_DEF( FT_Error )
-  af_cjk_hints_init( AF_GlyphHints  hints,
-                     AF_CJKMetrics  metrics )
+  af_cjk_hints_init( AF_GlyphHints    hints,
+                     AF_StyleMetrics  metrics_ )   /* AF_CJKMetrics */
   {
+    AF_CJKMetrics   metrics = (AF_CJKMetrics)metrics_;
     FT_Render_Mode  mode;
     FT_UInt32       scaler_flags, other_flags;
 
@@ -1628,7 +1634,7 @@
 
     stem_edge->pos = base_edge->pos + fitted_width;
 
-    FT_TRACE5(( "  CJKLINK: edge %ld @%d (opos=%.2f) linked to %.2f,"
+    FT_TRACE5(( "  CJKLINK: edge %td @%d (opos=%.2f) linked to %.2f,"
                 " dist was %.2f, now %.2f\n",
                 stem_edge - hints->axis[dim].edges, stem_edge->fpos,
                 (double)stem_edge->opos / 64,
@@ -1852,7 +1858,7 @@
           continue;
 
 #ifdef FT_DEBUG_LEVEL_TRACE
-        FT_TRACE5(( "  CJKBLUE: edge %ld @%d (opos=%.2f) snapped to %.2f,"
+        FT_TRACE5(( "  CJKBLUE: edge %td @%d (opos=%.2f) snapped to %.2f,"
                     " was %.2f\n",
                     edge1 - edges, edge1->fpos, (double)edge1->opos / 64,
                     (double)blue->fit / 64, (double)edge1->pos / 64 ));
@@ -1916,7 +1922,7 @@
       /* this should not happen, but it's better to be safe */
       if ( edge2->blue_edge )
       {
-        FT_TRACE5(( "ASSERTION FAILED for edge %ld\n", edge2-edges ));
+        FT_TRACE5(( "ASSERTION FAILED for edge %td\n", edge2 - edges ));
 
         af_cjk_align_linked_edge( hints, dim, edge2, edge );
         edge->flags |= AF_EDGE_DONE;
@@ -2268,11 +2274,13 @@
   /* Apply the complete hinting algorithm to a CJK glyph. */
 
   FT_LOCAL_DEF( FT_Error )
-  af_cjk_hints_apply( FT_UInt        glyph_index,
-                      AF_GlyphHints  hints,
-                      FT_Outline*    outline,
-                      AF_CJKMetrics  metrics )
+  af_cjk_hints_apply( FT_UInt          glyph_index,
+                      AF_GlyphHints    hints,
+                      FT_Outline*      outline,
+                      AF_StyleMetrics  metrics_ )   /* AF_CJKMetrics */
   {
+    AF_CJKMetrics  metrics = (AF_CJKMetrics)metrics_;
+
     FT_Error  error;
     int       dim;
 
diff --git a/src/autofit/afcjk.h b/src/autofit/afcjk.h
index bd7b81b..f380ef6 100644
--- a/src/autofit/afcjk.h
+++ b/src/autofit/afcjk.h
@@ -103,22 +103,22 @@
 
 #ifdef AF_CONFIG_OPTION_CJK
   FT_LOCAL( FT_Error )
-  af_cjk_metrics_init( AF_CJKMetrics  metrics,
-                       FT_Face        face );
+  af_cjk_metrics_init( AF_StyleMetrics  metrics,
+                       FT_Face          face );
 
   FT_LOCAL( void )
-  af_cjk_metrics_scale( AF_CJKMetrics  metrics,
-                        AF_Scaler      scaler );
+  af_cjk_metrics_scale( AF_StyleMetrics  metrics,
+                        AF_Scaler        scaler );
 
   FT_LOCAL( FT_Error )
-  af_cjk_hints_init( AF_GlyphHints  hints,
-                     AF_CJKMetrics  metrics );
+  af_cjk_hints_init( AF_GlyphHints    hints,
+                     AF_StyleMetrics  metrics );
 
   FT_LOCAL( FT_Error )
-  af_cjk_hints_apply( FT_UInt        glyph_index,
-                      AF_GlyphHints  hints,
-                      FT_Outline*    outline,
-                      AF_CJKMetrics  metrics );
+  af_cjk_hints_apply( FT_UInt          glyph_index,
+                      AF_GlyphHints    hints,
+                      FT_Outline*      outline,
+                      AF_StyleMetrics  metrics );
 
   /* shared; called from afindic.c */
   FT_LOCAL( void )
diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c
index ede27eb..b195757 100644
--- a/src/autofit/afglobal.c
+++ b/src/autofit/afglobal.c
@@ -376,8 +376,11 @@
 
 
   FT_LOCAL_DEF( void )
-  af_face_globals_free( AF_FaceGlobals  globals )
+  af_face_globals_free( void*  globals_ )
   {
+    AF_FaceGlobals  globals = (AF_FaceGlobals)globals_;
+
+
     if ( globals )
     {
       FT_Memory  memory = globals->face->memory;
diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h
index 83a7c2f..66170e4 100644
--- a/src/autofit/afglobal.h
+++ b/src/autofit/afglobal.h
@@ -156,7 +156,7 @@
                                AF_StyleMetrics  *ametrics );
 
   FT_LOCAL( void )
-  af_face_globals_free( AF_FaceGlobals  globals );
+  af_face_globals_free( void*  globals );
 
   FT_LOCAL( FT_Bool )
   af_face_globals_is_digit( AF_FaceGlobals  globals,
diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c
index 6515af9..e4a378f 100644
--- a/src/autofit/afhints.c
+++ b/src/autofit/afhints.c
@@ -320,8 +320,9 @@
 
 
   static char*
-  af_print_idx( char* p,
-                int   idx )
+  af_print_idx( char*   p,
+                size_t  n,
+                int     idx )
   {
     if ( idx == -1 )
     {
@@ -330,7 +331,7 @@
       p[2] = '\0';
     }
     else
-      ft_sprintf( p, "%d", idx );
+      ft_snprintf( p, n, "%d", idx );
 
     return p;
   }
@@ -457,12 +458,12 @@
                 " %5d %5d %7.2f %7.2f %7.2f %7.2f"
                 " %5s %5s %5s %5s\n",
                 point_idx,
-                af_print_idx( buf1,
+                af_print_idx( buf1, 16,
                               af_get_edge_index( hints, segment_idx_1, 1 ) ),
-                af_print_idx( buf2, segment_idx_1 ),
-                af_print_idx( buf3,
+                af_print_idx( buf2, 16, segment_idx_1 ),
+                af_print_idx( buf3, 16,
                               af_get_edge_index( hints, segment_idx_0, 0 ) ),
-                af_print_idx( buf4, segment_idx_0 ),
+                af_print_idx( buf4, 16, segment_idx_0 ),
                 ( point->flags & AF_FLAG_NEAR )
                   ? " near "
                   : ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
@@ -476,18 +477,22 @@
                 (double)point->x / 64,
                 (double)point->y / 64,
 
-                af_print_idx( buf5, af_get_strong_edge_index( hints,
-                                                              point->before,
-                                                              1 ) ),
-                af_print_idx( buf6, af_get_strong_edge_index( hints,
-                                                              point->after,
-                                                              1 ) ),
-                af_print_idx( buf7, af_get_strong_edge_index( hints,
-                                                              point->before,
-                                                              0 ) ),
-                af_print_idx( buf8, af_get_strong_edge_index( hints,
-                                                              point->after,
-                                                              0 ) ) ));
+                af_print_idx( buf5, 16,
+                              af_get_strong_edge_index( hints,
+                                                        point->before,
+                                                        1 ) ),
+                af_print_idx( buf6, 16,
+                              af_get_strong_edge_index( hints,
+                                                        point->after,
+                                                        1 ) ),
+                af_print_idx( buf7, 16,
+                              af_get_strong_edge_index( hints,
+                                                        point->before,
+                                                        0 ) ),
+                af_print_idx( buf8, 16,
+                              af_get_strong_edge_index( hints,
+                                                        point->after,
+                                                        0 ) ) ));
     }
     AF_DUMP(( "\n" ));
   }
@@ -574,9 +579,12 @@
                   AF_INDEX_NUM( seg->first, points ),
                   AF_INDEX_NUM( seg->last, points ),
 
-                  af_print_idx( buf1, AF_INDEX_NUM( seg->link, segments ) ),
-                  af_print_idx( buf2, AF_INDEX_NUM( seg->serif, segments ) ),
-                  af_print_idx( buf3, AF_INDEX_NUM( seg->edge, edges ) ),
+                  af_print_idx( buf1, 16,
+                                AF_INDEX_NUM( seg->link, segments ) ),
+                  af_print_idx( buf2, 16,
+                                AF_INDEX_NUM( seg->serif, segments ) ),
+                  af_print_idx( buf3, 16,
+                                AF_INDEX_NUM( seg->edge, edges ) ),
 
                   seg->height,
                   seg->height - ( seg->max_coord - seg->min_coord ),
@@ -716,8 +724,10 @@
                   AF_INDEX_NUM( edge, edges ),
                   (double)(int)edge->opos / 64,
                   af_dir_str( (AF_Direction)edge->dir ),
-                  af_print_idx( buf1, AF_INDEX_NUM( edge->link, edges ) ),
-                  af_print_idx( buf2, AF_INDEX_NUM( edge->serif, edges ) ),
+                  af_print_idx( buf1, 16,
+                                AF_INDEX_NUM( edge->link, edges ) ),
+                  af_print_idx( buf2, 16,
+                                AF_INDEX_NUM( edge->serif, edges ) ),
 
                   edge->blue_edge ? 'y' : 'n',
                   (double)edge->opos / 64,
diff --git a/src/autofit/afindic.c b/src/autofit/afindic.c
index 289a09d..7fb12c6 100644
--- a/src/autofit/afindic.c
+++ b/src/autofit/afindic.c
@@ -28,9 +28,12 @@
 
 
   static FT_Error
-  af_indic_metrics_init( AF_CJKMetrics  metrics,
-                         FT_Face        face )
+  af_indic_metrics_init( AF_StyleMetrics  metrics_, /* AF_CJKMetrics */
+                         FT_Face          face )
   {
+    AF_CJKMetrics  metrics = (AF_CJKMetrics)metrics_;
+
+
     /* skip blue zone init in CJK routines */
     FT_CharMap  oldmap = face->charmap;
 
@@ -55,8 +58,8 @@
 
 
   static void
-  af_indic_metrics_scale( AF_CJKMetrics  metrics,
-                          AF_Scaler      scaler )
+  af_indic_metrics_scale( AF_StyleMetrics  metrics,
+                          AF_Scaler        scaler )
   {
     /* use CJK routines */
     af_cjk_metrics_scale( metrics, scaler );
@@ -64,8 +67,8 @@
 
 
   static FT_Error
-  af_indic_hints_init( AF_GlyphHints  hints,
-                       AF_CJKMetrics  metrics )
+  af_indic_hints_init( AF_GlyphHints    hints,
+                       AF_StyleMetrics  metrics )
   {
     /* use CJK routines */
     return af_cjk_hints_init( hints, metrics );
@@ -73,10 +76,10 @@
 
 
   static FT_Error
-  af_indic_hints_apply( FT_UInt        glyph_index,
-                        AF_GlyphHints  hints,
-                        FT_Outline*    outline,
-                        AF_CJKMetrics  metrics )
+  af_indic_hints_apply( FT_UInt          glyph_index,
+                        AF_GlyphHints    hints,
+                        FT_Outline*      outline,
+                        AF_StyleMetrics  metrics )
   {
     /* use CJK routines */
     return af_cjk_hints_apply( glyph_index, hints, outline, metrics );
@@ -87,10 +90,13 @@
   /* metrics class.                                             */
 
   static void
-  af_indic_get_standard_widths( AF_CJKMetrics  metrics,
-                                FT_Pos*        stdHW,
-                                FT_Pos*        stdVW )
+  af_indic_get_standard_widths( AF_StyleMetrics  metrics_, /* AF_CJKMetrics */
+                                FT_Pos*          stdHW,
+                                FT_Pos*          stdVW )
   {
+    AF_CJKMetrics  metrics = (AF_CJKMetrics)metrics_;
+
+
     if ( stdHW )
       *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width;
 
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 4b3c59b..b86367a 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -496,23 +496,20 @@
           /* now compute min or max point indices and coordinates */
           points             = outline.points;
           best_point         = -1;
+          best_contour_first = -1;
+          best_contour_last  = -1;
           best_y             = 0;  /* make compiler happy */
-          best_contour_first = 0;  /* ditto */
-          best_contour_last  = 0;  /* ditto */
 
           {
             FT_Int  nn;
-            FT_Int  first = 0;
-            FT_Int  last  = -1;
+            FT_Int  pp, first, last;
 
 
-            for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ )
+            last = -1;
+            for ( nn = 0; nn < outline.n_contours; nn++ )
             {
-              FT_Int  old_best_point = best_point;
-              FT_Int  pp;
-
-
-              last = outline.contours[nn];
+              first = last + 1;
+              last  = outline.contours[nn];
 
               /* Avoid single-point contours since they are never      */
               /* rasterized.  In some fonts, they correspond to mark   */
@@ -551,7 +548,7 @@
                 }
               }
 
-              if ( best_point != old_best_point )
+              if ( best_point > best_contour_last )
               {
                 best_contour_first = first;
                 best_contour_last  = last;
@@ -1025,7 +1022,7 @@
         {
           *a = *b;
           FT_TRACE5(( "blue zone overlap:"
-                      " adjusting %s %ld to %ld\n",
+                      " adjusting %s %td to %ld\n",
                       a_is_top ? "overshoot" : "reference",
                       blue_sorted[i] - axis->blues,
                       *a ));
@@ -1068,8 +1065,8 @@
   af_latin_metrics_check_digits( AF_LatinMetrics  metrics,
                                  FT_Face          face )
   {
-    FT_Bool   started = 0, same_width = 1;
-    FT_Fixed  advance = 0, old_advance = 0;
+    FT_Bool  started = 0, same_width = 1;
+    FT_Long  advance = 0, old_advance = 0;
 
     /* If HarfBuzz is not available, we need a pointer to a single */
     /* unsigned long value.                                        */
@@ -1134,9 +1131,11 @@
   /* Initialize global metrics. */
 
   FT_LOCAL_DEF( FT_Error )
-  af_latin_metrics_init( AF_LatinMetrics  metrics,
+  af_latin_metrics_init( AF_StyleMetrics  metrics_,   /* AF_LatinMetrics */
                          FT_Face          face )
   {
+    AF_LatinMetrics  metrics = (AF_LatinMetrics)metrics_;
+
     FT_Error  error = FT_Err_Ok;
 
     FT_CharMap  oldmap = face->charmap;
@@ -1489,9 +1488,12 @@
   /* Scale global values in both directions. */
 
   FT_LOCAL_DEF( void )
-  af_latin_metrics_scale( AF_LatinMetrics  metrics,
+  af_latin_metrics_scale( AF_StyleMetrics  metrics_,   /* AF_LatinMetrics */
                           AF_Scaler        scaler )
   {
+    AF_LatinMetrics  metrics = (AF_LatinMetrics)metrics_;
+
+
     metrics->root.scaler.render_mode = scaler->render_mode;
     metrics->root.scaler.face        = scaler->face;
     metrics->root.scaler.flags       = scaler->flags;
@@ -1504,11 +1506,14 @@
   /* Extract standard_width from writing system/script specific */
   /* metrics class.                                             */
 
-  FT_LOCAL_DEF( void )
-  af_latin_get_standard_widths( AF_LatinMetrics  metrics,
+  FT_CALLBACK_DEF( void )
+  af_latin_get_standard_widths( AF_StyleMetrics  metrics_, /* AF_LatinMetrics */
                                 FT_Pos*          stdHW,
                                 FT_Pos*          stdVW )
   {
+    AF_LatinMetrics  metrics = (AF_LatinMetrics)metrics_;
+
+
     if ( stdHW )
       *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width;
 
@@ -2041,7 +2046,7 @@
             max = seg2->max_coord;
 
           /* compute maximum coordinate difference of the two segments */
-          /* (this is, how much they overlap)                          */
+          /* (that is, how much they overlap)                          */
           len = max - min;
           if ( len >= len_threshold )
           {
@@ -2610,8 +2615,10 @@
 
   static FT_Error
   af_latin_hints_init( AF_GlyphHints    hints,
-                       AF_LatinMetrics  metrics )
+                       AF_StyleMetrics  metrics_ )   /* AF_LatinMetrics */
   {
+    AF_LatinMetrics  metrics = (AF_LatinMetrics)metrics_;
+
     FT_Render_Mode  mode;
     FT_UInt32       scaler_flags, other_flags;
     FT_Face         face = metrics->root.scaler.face;
@@ -2953,7 +2960,7 @@
 
     stem_edge->pos = base_edge->pos + fitted_width;
 
-    FT_TRACE5(( "  LINK: edge %ld (opos=%.2f) linked to %.2f,"
+    FT_TRACE5(( "  LINK: edge %td (opos=%.2f) linked to %.2f,"
                 " dist was %.2f, now %.2f\n",
                 stem_edge - hints->axis[dim].edges,
                 (double)stem_edge->opos / 64, (double)stem_edge->pos / 64,
@@ -3078,13 +3085,13 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
         if ( !anchor )
-          FT_TRACE5(( "  BLUE_ANCHOR: edge %ld (opos=%.2f) snapped to %.2f,"
-                      " was %.2f (anchor=edge %ld)\n",
+          FT_TRACE5(( "  BLUE_ANCHOR: edge %td (opos=%.2f) snapped to %.2f,"
+                      " was %.2f (anchor=edge %td)\n",
                       edge1 - edges,
                       (double)edge1->opos / 64, (double)blue->fit / 64,
                       (double)edge1->pos / 64, edge - edges ));
         else
-          FT_TRACE5(( "  BLUE: edge %ld (opos=%.2f) snapped to %.2f,"
+          FT_TRACE5(( "  BLUE: edge %td (opos=%.2f) snapped to %.2f,"
                       " was %.2f\n",
                       edge1 - edges,
                       (double)edge1->opos / 64, (double)blue->fit / 64,
@@ -3134,7 +3141,7 @@
       /* this should not happen, but it's better to be safe */
       if ( edge2->blue_edge )
       {
-        FT_TRACE5(( "  ASSERTION FAILED for edge %ld\n", edge2 - edges ));
+        FT_TRACE5(( "  ASSERTION FAILED for edge %td\n", edge2 - edges ));
 
         af_latin_align_linked_edge( hints, dim, edge2, edge );
         edge->flags |= AF_EDGE_DONE;
@@ -3202,7 +3209,7 @@
         anchor       = edge;
         edge->flags |= AF_EDGE_DONE;
 
-        FT_TRACE5(( "  ANCHOR: edge %ld (opos=%.2f) and %ld (opos=%.2f)"
+        FT_TRACE5(( "  ANCHOR: edge %td (opos=%.2f) and %td (opos=%.2f)"
                     " snapped to %.2f and %.2f\n",
                     edge - edges, (double)edge->opos / 64,
                     edge2 - edges, (double)edge2->opos / 64,
@@ -3231,7 +3238,7 @@
 
         if ( edge2->flags & AF_EDGE_DONE )
         {
-          FT_TRACE5(( "  ADJUST: edge %ld (pos=%.2f) moved to %.2f\n",
+          FT_TRACE5(( "  ADJUST: edge %td (pos=%.2f) moved to %.2f\n",
                       edge - edges, (double)edge->pos / 64,
                       (double)( edge2->pos - cur_len ) / 64 ));
 
@@ -3272,7 +3279,7 @@
           edge->pos  = cur_pos1 - cur_len / 2;
           edge2->pos = cur_pos1 + cur_len / 2;
 
-          FT_TRACE5(( "  STEM: edge %ld (opos=%.2f) linked to %ld (opos=%.2f)"
+          FT_TRACE5(( "  STEM: edge %td (opos=%.2f) linked to %td (opos=%.2f)"
                       " snapped to %.2f and %.2f\n",
                       edge - edges, (double)edge->opos / 64,
                       edge2 - edges, (double)edge2->opos / 64,
@@ -3303,7 +3310,7 @@
           edge->pos  = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;
           edge2->pos = edge->pos + cur_len;
 
-          FT_TRACE5(( "  STEM: edge %ld (opos=%.2f) linked to %ld (opos=%.2f)"
+          FT_TRACE5(( "  STEM: edge %td (opos=%.2f) linked to %td (opos=%.2f)"
                       " snapped to %.2f and %.2f\n",
                       edge - edges, (double)edge->opos / 64,
                       edge2 - edges, (double)edge2->opos / 64,
@@ -3326,7 +3333,7 @@
           if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 )
           {
 #ifdef FT_DEBUG_LEVEL_TRACE
-            FT_TRACE5(( "  BOUND: edge %ld (pos=%.2f) moved to %.2f\n",
+            FT_TRACE5(( "  BOUND: edge %td (pos=%.2f) moved to %.2f\n",
                         edge - edges,
                         (double)edge->pos / 64,
                         (double)edge[-1].pos / 64 ));
@@ -3428,7 +3435,7 @@
         if ( delta < 64 + 16 )
         {
           af_latin_align_serif_edge( hints, edge->serif, edge );
-          FT_TRACE5(( "  SERIF: edge %ld (opos=%.2f) serif to %ld (opos=%.2f)"
+          FT_TRACE5(( "  SERIF: edge %td (opos=%.2f) serif to %td (opos=%.2f)"
                       " aligned to %.2f\n",
                       edge - edges, (double)edge->opos / 64,
                       edge->serif - edges, (double)edge->serif->opos / 64,
@@ -3438,9 +3445,9 @@
         {
           edge->pos = FT_PIX_ROUND( edge->opos );
           anchor    = edge;
-          FT_TRACE5(( "  SERIF_ANCHOR: edge %ld (opos=%.2f)"
+          FT_TRACE5(( "  SERIF_ANCHOR: edge %td (opos=%.2f)"
                       " snapped to %.2f\n",
-                      edge-edges,
+                      edge - edges,
                       (double)edge->opos / 64, (double)edge->pos / 64 ));
         }
         else
@@ -3467,8 +3474,8 @@
                                      after->pos - before->pos,
                                      after->opos - before->opos );
 
-            FT_TRACE5(( "  SERIF_LINK1: edge %ld (opos=%.2f) snapped to %.2f"
-                        " from %ld (opos=%.2f)\n",
+            FT_TRACE5(( "  SERIF_LINK1: edge %td (opos=%.2f) snapped to %.2f"
+                        " from %td (opos=%.2f)\n",
                         edge - edges, (double)edge->opos / 64,
                         (double)edge->pos / 64,
                         before - edges, (double)before->opos / 64 ));
@@ -3477,7 +3484,7 @@
           {
             edge->pos = anchor->pos +
                         ( ( edge->opos - anchor->opos + 16 ) & ~31 );
-            FT_TRACE5(( "  SERIF_LINK2: edge %ld (opos=%.2f)"
+            FT_TRACE5(( "  SERIF_LINK2: edge %td (opos=%.2f)"
                         " snapped to %.2f\n",
                         edge - edges,
                         (double)edge->opos / 64, (double)edge->pos / 64 ));
@@ -3498,7 +3505,7 @@
           if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 )
           {
 #ifdef FT_DEBUG_LEVEL_TRACE
-            FT_TRACE5(( "  BOUND: edge %ld (pos=%.2f) moved to %.2f\n",
+            FT_TRACE5(( "  BOUND: edge %td (pos=%.2f) moved to %.2f\n",
                         edge - edges,
                         (double)edge->pos / 64,
                         (double)edge[-1].pos / 64 ));
@@ -3519,7 +3526,7 @@
           if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 )
           {
 #ifdef FT_DEBUG_LEVEL_TRACE
-            FT_TRACE5(( "  BOUND: edge %ld (pos=%.2f) moved to %.2f\n",
+            FT_TRACE5(( "  BOUND: edge %td (pos=%.2f) moved to %.2f\n",
                         edge - edges,
                         (double)edge->pos / 64,
                         (double)edge[1].pos / 64 ));
@@ -3547,8 +3554,10 @@
   af_latin_hints_apply( FT_UInt          glyph_index,
                         AF_GlyphHints    hints,
                         FT_Outline*      outline,
-                        AF_LatinMetrics  metrics )
+                        AF_StyleMetrics  metrics_ )    /* AF_LatinMetrics */
   {
+    AF_LatinMetrics  metrics = (AF_LatinMetrics)metrics_;
+
     FT_Error  error;
     int       dim;
 
diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h
index 3c6a7ee..31aa91d 100644
--- a/src/autofit/aflatin.h
+++ b/src/autofit/aflatin.h
@@ -116,11 +116,11 @@
 
 
   FT_LOCAL( FT_Error )
-  af_latin_metrics_init( AF_LatinMetrics  metrics,
+  af_latin_metrics_init( AF_StyleMetrics  metrics,
                          FT_Face          face );
 
   FT_LOCAL( void )
-  af_latin_metrics_scale( AF_LatinMetrics  metrics,
+  af_latin_metrics_scale( AF_StyleMetrics  metrics,
                           AF_Scaler        scaler );
 
   FT_LOCAL( void )
diff --git a/src/autofit/afloader.c b/src/autofit/afloader.c
index c808279..7c47d56 100644
--- a/src/autofit/afloader.c
+++ b/src/autofit/afloader.c
@@ -55,10 +55,8 @@
       error = af_face_globals_new( face, &loader->globals, module );
       if ( !error )
       {
-        face->autohint.data =
-          (FT_Pointer)loader->globals;
-        face->autohint.finalizer =
-          (FT_Generic_Finalizer)af_face_globals_free;
+        face->autohint.data      = (FT_Pointer)loader->globals;
+        face->autohint.finalizer = af_face_globals_free;
       }
     }
 
diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c
index 92e5156..20a6b96 100644
--- a/src/autofit/afmodule.c
+++ b/src/autofit/afmodule.c
@@ -89,10 +89,8 @@
       error = af_face_globals_new( face, &globals, module );
       if ( !error )
       {
-        face->autohint.data =
-          (FT_Pointer)globals;
-        face->autohint.finalizer =
-          (FT_Generic_Finalizer)af_face_globals_free;
+        face->autohint.data      = (FT_Pointer)globals;
+        face->autohint.finalizer = af_face_globals_free;
       }
     }
 
@@ -374,8 +372,9 @@
   FT_DEFINE_SERVICE_PROPERTIESREC(
     af_service_properties,
 
-    (FT_Properties_SetFunc)af_property_set,        /* set_property */
-    (FT_Properties_GetFunc)af_property_get )       /* get_property */
+    af_property_set,  /* FT_Properties_SetFunc set_property */
+    af_property_get   /* FT_Properties_GetFunc get_property */
+  )
 
 
   FT_DEFINE_SERVICEDESCREC1(
@@ -430,12 +429,14 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  af_autofitter_load_glyph( AF_Module     module,
-                            FT_GlyphSlot  slot,
-                            FT_Size       size,
-                            FT_UInt       glyph_index,
-                            FT_Int32      load_flags )
+  af_autofitter_load_glyph( FT_AutoHinter  module_,
+                            FT_GlyphSlot   slot,
+                            FT_Size        size,
+                            FT_UInt        glyph_index,
+                            FT_Int32       load_flags )
   {
+    AF_Module  module = (AF_Module)module_;
+
     FT_Error   error  = FT_Err_Ok;
     FT_Memory  memory = module->root.library->memory;
 
@@ -499,10 +500,10 @@
   FT_DEFINE_AUTOHINTER_INTERFACE(
     af_autofitter_interface,
 
-    NULL,                                                    /* reset_face */
-    NULL,                                              /* get_global_hints */
-    NULL,                                             /* done_global_hints */
-    (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph    /* load_glyph */
+    NULL,                     /* FT_AutoHinter_GlobalResetFunc reset_face        */
+    NULL,                     /* FT_AutoHinter_GlobalGetFunc   get_global_hints  */
+    NULL,                     /* FT_AutoHinter_GlobalDoneFunc  done_global_hints */
+    af_autofitter_load_glyph  /* FT_AutoHinter_GlyphLoadFunc   load_glyph        */
   )
 
   FT_DEFINE_MODULE(
@@ -517,9 +518,9 @@
 
     (const void*)&af_autofitter_interface,
 
-    (FT_Module_Constructor)af_autofitter_init,  /* module_init   */
-    (FT_Module_Destructor) af_autofitter_done,  /* module_done   */
-    (FT_Module_Requester)  af_get_interface     /* get_interface */
+    af_autofitter_init,  /* FT_Module_Constructor module_init   */
+    af_autofitter_done,  /* FT_Module_Destructor  module_done   */
+    af_get_interface     /* FT_Module_Requester   get_interface */
   )
 
 
diff --git a/src/autofit/afshaper.c b/src/autofit/afshaper.c
index 1b8b870..abc6f1d 100644
--- a/src/autofit/afshaper.c
+++ b/src/autofit/afshaper.c
@@ -258,7 +258,7 @@
     /*
      * We now check whether we can construct blue zones, using glyphs
      * covered by the feature only.  In case there is not a single zone
-     * (this is, not a single character is covered), we skip this coverage.
+     * (that is, not a single character is covered), we skip this coverage.
      *
      */
     if ( style_class->coverage != AF_COVERAGE_DEFAULT )
@@ -313,9 +313,9 @@
      * hinted and usually rendered glyph.
      *
      * Consider the superscript feature of font `pala.ttf': Some of the
-     * glyphs are `real', this is, they have a zero vertical offset, but
+     * glyphs are `real', that is, they have a zero vertical offset, but
      * most of them are small caps glyphs shifted up to the superscript
-     * position (this is, the `sups' feature is present in both the GSUB and
+     * position (that is, the `sups' feature is present in both the GSUB and
      * GPOS tables).  The code for blue zones computation actually uses a
      * feature's y offset so that the `real' glyphs get correct hints.  But
      * later on it is impossible to decide whether a glyph index belongs to,
diff --git a/src/autofit/ft-hb.c b/src/autofit/ft-hb.c
index 09a8401..71aee04 100644
--- a/src/autofit/ft-hb.c
+++ b/src/autofit/ft-hb.c
@@ -108,7 +108,7 @@
 #else /* !FT_CONFIG_OPTION_USE_HARFBUZZ */
 
 /* ANSI C doesn't like empty source files */
-typedef int  _ft_hb_dummy;
+typedef int  ft_hb_dummy_;
 
 #endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ */
 
diff --git a/src/base/ftbbox.c b/src/base/ftbbox.c
index 7dd7188..385fea4 100644
--- a/src/base/ftbbox.c
+++ b/src/base/ftbbox.c
@@ -82,10 +82,13 @@
    * @Return:
    *   Always 0.  Needed for the interface only.
    */
-  static int
-  BBox_Move_To( FT_Vector*  to,
-                TBBox_Rec*  user )
+  FT_CALLBACK_DEF( int )
+  BBox_Move_To( const FT_Vector*  to,
+                void*             user_ )
   {
+    TBBox_Rec*  user = (TBBox_Rec*)user_;
+
+
     FT_UPDATE_BBOX( to, user->bbox );
 
     user->last = *to;
@@ -116,10 +119,13 @@
    * @Return:
    *   Always 0.  Needed for the interface only.
    */
-  static int
-  BBox_Line_To( FT_Vector*  to,
-                TBBox_Rec*  user )
+  FT_CALLBACK_DEF( int )
+  BBox_Line_To( const FT_Vector*  to,
+                void*             user_ )
   {
+    TBBox_Rec*  user = (TBBox_Rec*)user_;
+
+
     user->last = *to;
 
     return 0;
@@ -205,11 +211,14 @@
    *   In the case of a non-monotonous arc, we compute directly the
    *   extremum coordinates, as it is sufficiently fast.
    */
-  static int
-  BBox_Conic_To( FT_Vector*  control,
-                 FT_Vector*  to,
-                 TBBox_Rec*  user )
+  FT_CALLBACK_DEF( int )
+  BBox_Conic_To( const FT_Vector*  control,
+                 const FT_Vector*  to,
+                 void*             user_ )
   {
+    TBBox_Rec*  user = (TBBox_Rec*)user_;
+
+
     /* in case `to' is implicit and not included in bbox yet */
     FT_UPDATE_BBOX( to, user->bbox );
 
@@ -410,12 +419,15 @@
    *   In the case of a non-monotonous arc, we don't compute directly
    *   extremum coordinates, we subdivide instead.
    */
-  static int
-  BBox_Cubic_To( FT_Vector*  control1,
-                 FT_Vector*  control2,
-                 FT_Vector*  to,
-                 TBBox_Rec*  user )
+  FT_CALLBACK_DEF( int )
+  BBox_Cubic_To( const FT_Vector*  control1,
+                 const FT_Vector*  control2,
+                 const FT_Vector*  to,
+                 void*             user_ )
   {
+    TBBox_Rec*  user = (TBBox_Rec*)user_;
+
+
     /* We don't need to check `to' since it is always an on-point,    */
     /* thus within the bbox.  Only segments with an off-point outside */
     /* the bbox can possibly reach new extreme values.                */
diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c
index 13e74f3..c5bc7e3 100644
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -749,65 +749,43 @@
   FT_BASE_DEF( FT_Bool )
   FT_Matrix_Check( const FT_Matrix*  matrix )
   {
-    FT_Matrix  m;
-    FT_Fixed   val[4];
-    FT_Fixed   nonzero_minval, maxval;
-    FT_Fixed   temp1, temp2;
-    FT_UInt    i;
+    FT_Fixed  xx, xy, yx, yy;
+    FT_Fixed  val;
+    FT_Int    shift;
+    FT_ULong  temp1, temp2;
 
 
     if ( !matrix )
       return 0;
 
-    val[0] = FT_ABS( matrix->xx );
-    val[1] = FT_ABS( matrix->xy );
-    val[2] = FT_ABS( matrix->yx );
-    val[3] = FT_ABS( matrix->yy );
+    xx  = matrix->xx;
+    xy  = matrix->xy;
+    yx  = matrix->yx;
+    yy  = matrix->yy;
+    val = FT_ABS( xx ) | FT_ABS( xy ) | FT_ABS( yx ) | FT_ABS( yy );
 
-    /*
-     * To avoid overflow, we ensure that each value is not larger than
-     *
-     *   int(sqrt(2^31 / 4)) = 23170  ;
-     *
-     * we also check that no value becomes zero if we have to scale.
-     */
-
-    maxval         = 0;
-    nonzero_minval = FT_LONG_MAX;
-
-    for ( i = 0; i < 4; i++ )
-    {
-      if ( val[i] > maxval )
-        maxval = val[i];
-      if ( val[i] && val[i] < nonzero_minval )
-        nonzero_minval = val[i];
-    }
-
-    /* we only handle 32bit values */
-    if ( maxval > 0x7FFFFFFFL )
+    /* we only handle non-zero 32-bit values */
+    if ( !val || val > 0x7FFFFFFFL )
       return 0;
 
-    if ( maxval > 23170 )
+    /* Scale matrix to avoid the temp1 overflow, which is */
+    /* more stringent than avoiding the temp2 overflow.   */
+
+    shift = FT_MSB( val ) - 12;
+
+    if ( shift > 0 )
     {
-      FT_Fixed  scale = FT_DivFix( maxval, 23170 );
-
-
-      if ( !FT_DivFix( nonzero_minval, scale ) )
-        return 0;    /* value range too large */
-
-      m.xx = FT_DivFix( matrix->xx, scale );
-      m.xy = FT_DivFix( matrix->xy, scale );
-      m.yx = FT_DivFix( matrix->yx, scale );
-      m.yy = FT_DivFix( matrix->yy, scale );
+      xx >>= shift;
+      xy >>= shift;
+      yx >>= shift;
+      yy >>= shift;
     }
-    else
-      m = *matrix;
 
-    temp1 = FT_ABS( m.xx * m.yy - m.xy * m.yx );
-    temp2 = m.xx * m.xx + m.xy * m.xy + m.yx * m.yx + m.yy * m.yy;
+    temp1 = 32U * (FT_ULong)FT_ABS( xx * yy - xy * yx );
+    temp2 = (FT_ULong)( xx * xx ) + (FT_ULong)( xy * xy ) +
+            (FT_ULong)( yx * yx ) + (FT_ULong)( yy * yy );
 
-    if ( temp1 == 0         ||
-         temp2 / temp1 > 50 )
+    if ( temp1 <= temp2 )
       return 0;
 
     return 1;
@@ -1061,7 +1039,7 @@
     /*                                                           */
     /* 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      */
+    /* vectors is `dominant', that is, much larger than the      */
     /* other vector, we thus always have a flat corner.          */
     /*                                                           */
     /*                hypotenuse                                 */
@@ -1092,9 +1070,6 @@
   {
     FT_UInt   i;
     FT_Int64  temp;
-#ifndef FT_INT64
-    FT_Int64  halfUnit;
-#endif
 
 
 #ifdef FT_INT64
@@ -1103,7 +1078,7 @@
     for ( i = 0; i < count; ++i )
       temp += (FT_Int64)s[i] * f[i];
 
-    return ( temp + 0x8000 ) >> 16;
+    return (FT_Int32)( ( temp + 0x8000 ) >> 16 );
 #else
     temp.hi = 0;
     temp.lo = 0;
@@ -1139,13 +1114,10 @@
       FT_Add64( &temp, &multResult, &temp );
     }
 
-    /* Round value. */
-    halfUnit.hi = 0;
-    halfUnit.lo = 0x8000;
-    FT_Add64( &temp, &halfUnit, &temp );
+    /* Shift and round value. */
+    return (FT_Int32)( ( ( temp.hi << 16 ) | ( temp.lo >> 16 ) )
+                                     + ( 1 & ( temp.lo >> 15 ) ) );
 
-    return (FT_Int32)( ( (FT_Int32)( temp.hi & 0xFFFF ) << 16 ) |
-                                   ( temp.lo >> 16 )            );
 
 #endif /* !FT_INT64 */
 
diff --git a/src/base/ftdbgmem.c b/src/base/ftdbgmem.c
index 6730c4c..8fab50d 100644
--- a/src/base/ftdbgmem.c
+++ b/src/base/ftdbgmem.c
@@ -963,7 +963,7 @@
 #else  /* !FT_DEBUG_MEMORY */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _debug_mem_dummy;
+  typedef int  debug_mem_dummy_;
 
 #endif /* !FT_DEBUG_MEMORY */
 
diff --git a/src/base/ftmac.c b/src/base/ftmac.c
index de34e83..492d055 100644
--- a/src/base/ftmac.c
+++ b/src/base/ftmac.c
@@ -1082,7 +1082,7 @@
 #else /* !FT_MACINTOSH */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _ft_mac_dummy;
+  typedef int  ft_mac_dummy_;
 
 #endif /* !FT_MACINTOSH */
 
diff --git a/src/base/ftmm.c b/src/base/ftmm.c
index a2b4bd0..9e2dd7e 100644
--- a/src/base/ftmm.c
+++ b/src/base/ftmm.c
@@ -185,6 +185,14 @@
       error = FT_ERR( Invalid_Argument );
       if ( service->set_mm_design )
         error = service->set_mm_design( face, num_coords, coords );
+
+      if ( !error )
+      {
+        if ( num_coords )
+          face->face_flags |= FT_FACE_FLAG_VARIATION;
+        else
+          face->face_flags &= ~FT_FACE_FLAG_VARIATION;
+      }
     }
 
     /* enforce recomputation of auto-hinting data */
@@ -220,6 +228,14 @@
       error = FT_ERR( Invalid_Argument );
       if ( service->set_mm_weightvector )
         error = service->set_mm_weightvector( face, len, weightvector );
+
+      if ( !error )
+      {
+        if ( len )
+          face->face_flags |= FT_FACE_FLAG_VARIATION;
+        else
+          face->face_flags &= ~FT_FACE_FLAG_VARIATION;
+      }
     }
 
     /* enforce recomputation of auto-hinting data */
@@ -283,6 +299,30 @@
       if ( service_mm->set_var_design )
         error = service_mm->set_var_design( face, num_coords, coords );
 
+      if ( !error || error == -1 )
+      {
+        FT_Bool  is_variation_old = FT_IS_VARIATION( face );
+
+
+        if ( num_coords )
+          face->face_flags |= FT_FACE_FLAG_VARIATION;
+        else
+          face->face_flags &= ~FT_FACE_FLAG_VARIATION;
+
+        if ( service_mm->construct_ps_name )
+        {
+          if ( error == -1 )
+          {
+            /* The PS name of a named instance and a non-named instance */
+            /* usually differs, even if the axis values are identical.  */
+            if ( is_variation_old != FT_IS_VARIATION( face ) )
+              service_mm->construct_ps_name( face );
+          }
+          else
+            service_mm->construct_ps_name( face );
+        }
+      }
+
       /* internal error code -1 means `no change'; we can exit immediately */
       if ( error == -1 )
         return FT_Err_Ok;
@@ -359,6 +399,30 @@
       if ( service_mm->set_mm_blend )
         error = service_mm->set_mm_blend( face, num_coords, coords );
 
+      if ( !error || error == -1 )
+      {
+        FT_Bool  is_variation_old = FT_IS_VARIATION( face );
+
+
+        if ( num_coords )
+          face->face_flags |= FT_FACE_FLAG_VARIATION;
+        else
+          face->face_flags &= ~FT_FACE_FLAG_VARIATION;
+
+        if ( service_mm->construct_ps_name )
+        {
+          if ( error == -1 )
+          {
+            /* The PS name of a named instance and a non-named instance */
+            /* usually differs, even if the axis values are identical.  */
+            if ( is_variation_old != FT_IS_VARIATION( face ) )
+              service_mm->construct_ps_name( face );
+          }
+          else
+            service_mm->construct_ps_name( face );
+        }
+      }
+
       /* internal error code -1 means `no change'; we can exit immediately */
       if ( error == -1 )
         return FT_Err_Ok;
@@ -410,6 +474,30 @@
       if ( service_mm->set_mm_blend )
         error = service_mm->set_mm_blend( face, num_coords, coords );
 
+      if ( !error || error == -1 )
+      {
+        FT_Bool  is_variation_old = FT_IS_VARIATION( face );
+
+
+        if ( num_coords )
+          face->face_flags |= FT_FACE_FLAG_VARIATION;
+        else
+          face->face_flags &= ~FT_FACE_FLAG_VARIATION;
+
+        if ( service_mm->construct_ps_name )
+        {
+          if ( error == -1 )
+          {
+            /* The PS name of a named instance and a non-named instance */
+            /* usually differs, even if the axis values are identical.  */
+            if ( is_variation_old != FT_IS_VARIATION( face ) )
+              service_mm->construct_ps_name( face );
+          }
+          else
+            service_mm->construct_ps_name( face );
+        }
+      }
+
       /* internal error code -1 means `no change'; we can exit immediately */
       if ( error == -1 )
         return FT_Err_Ok;
@@ -535,8 +623,35 @@
     if ( !error )
     {
       error = FT_ERR( Invalid_Argument );
-      if ( service_mm->set_instance )
-        error = service_mm->set_instance( face, instance_index );
+      if ( service_mm->set_named_instance )
+        error = service_mm->set_named_instance( face, instance_index );
+
+      if ( !error || error == -1 )
+      {
+        FT_Bool  is_variation_old = FT_IS_VARIATION( face );
+
+
+        face->face_flags &= ~FT_FACE_FLAG_VARIATION;
+        face->face_index  = ( instance_index << 16 )        |
+                            ( face->face_index & 0xFFFFL );
+
+        if ( service_mm->construct_ps_name )
+        {
+          if ( error == -1 )
+          {
+            /* The PS name of a named instance and a non-named instance */
+            /* usually differs, even if the axis values are identical.  */
+            if ( is_variation_old != FT_IS_VARIATION( face ) )
+              service_mm->construct_ps_name( face );
+          }
+          else
+            service_mm->construct_ps_name( face );
+        }
+      }
+
+      /* internal error code -1 means `no change'; we can exit immediately */
+      if ( error == -1 )
+        return FT_Err_Ok;
     }
 
     if ( !error )
@@ -554,11 +669,32 @@
       face->autohint.data = NULL;
     }
 
+    return error;
+  }
+
+
+  /* documentation is in ftmm.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_Default_Named_Instance( FT_Face   face,
+                                 FT_UInt  *instance_index )
+  {
+    FT_Error  error;
+
+    FT_Service_MultiMasters  service_mm = NULL;
+
+
+    /* check of `face' delayed to `ft_face_get_mm_service' */
+
+    error = ft_face_get_mm_service( face, &service_mm );
     if ( !error )
     {
-      face->face_index  = ( instance_index << 16 )        |
-                          ( face->face_index & 0xFFFFL );
-      face->face_flags &= ~FT_FACE_FLAG_VARIATION;
+      /* no error if `get_default_named_instance` is not available */
+      if ( service_mm->get_default_named_instance )
+        error = service_mm->get_default_named_instance( face,
+                                                        instance_index );
+      else
+        error = FT_Err_Ok;
     }
 
     return error;
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index ad6ef0a..89a25bc 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -1019,7 +1019,8 @@
       /*      elegant.                                            */
 
       /* try to load SVG documents if available */
-      if ( FT_HAS_SVG( face ) )
+      if ( ( load_flags & FT_LOAD_NO_SVG ) == 0 &&
+           FT_HAS_SVG( face )                   )
       {
         error = driver->clazz->load_glyph( slot, face->size,
                                            glyph_index,
@@ -1245,9 +1246,13 @@
   /* destructor for sizes list */
   static void
   destroy_size( FT_Memory  memory,
-                FT_Size    size,
-                FT_Driver  driver )
+                void*      size_,
+                void*      driver_ )
   {
+    FT_Size    size   = (FT_Size)size_;
+    FT_Driver  driver = (FT_Driver)driver_;
+
+
     /* finalize client-specific data */
     if ( size->generic.finalizer )
       size->generic.finalizer( size );
@@ -1293,10 +1298,12 @@
   /* destructor for faces list */
   static void
   destroy_face( FT_Memory  memory,
-                FT_Face    face,
-                FT_Driver  driver )
+                void*      face_,
+                void*      driver_ )
   {
-    FT_Driver_Class  clazz = driver->clazz;
+    FT_Face          face   = (FT_Face)face_;
+    FT_Driver        driver = (FT_Driver)driver_;
+    FT_Driver_Class  clazz  = driver->clazz;
 
 
     /* discard auto-hinting data */
@@ -1310,7 +1317,7 @@
 
     /* discard all sizes for this face */
     FT_List_Finalize( &face->sizes_list,
-                      (FT_List_Destructor)destroy_size,
+                      destroy_size,
                       memory,
                       driver );
     face->size = NULL;
@@ -1346,7 +1353,7 @@
   Destroy_Driver( FT_Driver  driver )
   {
     FT_List_Finalize( &driver->faces_list,
-                      (FT_List_Destructor)destroy_face,
+                      destroy_face,
                       driver->root.memory,
                       driver );
   }
@@ -1740,7 +1747,8 @@
     FT_Memory     memory = library->memory;
 
 
-    args.flags = 0;
+    args.driver = NULL;
+    args.flags  = 0;
 
     if ( driver_name )
     {
diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
index 30ff21f..134f39d 100644
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -58,7 +58,9 @@
     FT_Error    error;
 
     FT_Int   n;         /* index of contour in outline     */
-    FT_UInt  first;     /* index of first point in contour */
+    FT_Int   first;     /* index of first point in contour */
+    FT_Int   last;      /* index of last point in contour  */
+
     FT_Int   tag;       /* current point's state           */
 
     FT_Int   shift;
@@ -73,18 +75,17 @@
 
     shift = func_interface->shift;
     delta = func_interface->delta;
-    first = 0;
 
+    last = -1;
     for ( n = 0; n < outline->n_contours; n++ )
     {
-      FT_Int  last;  /* index of last point in contour */
+      FT_TRACE5(( "FT_Outline_Decompose: Contour %d\n", n ));
 
-
-      FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n ));
-
-      last = outline->contours[n];
-      if ( last < 0 )
+      first = last + 1;
+      last  = outline->contours[n];
+      if ( last < first )
         goto Invalid_Outline;
+
       limit = outline->points + last;
 
       v_start   = outline->points[first];
@@ -282,8 +283,6 @@
     Close:
       if ( error )
         goto Exit;
-
-      first = (FT_UInt)last + 1;
     }
 
     FT_TRACE5(( "FT_Outline_Decompose: Done\n" ));
@@ -368,7 +367,7 @@
       if ( n_points <= 0 || n_contours <= 0 )
         goto Bad;
 
-      end0 = end = -1;
+      end0 = -1;
       for ( n = 0; n < n_contours; n++ )
       {
         end = outline->contours[n];
@@ -380,7 +379,7 @@
         end0 = end;
       }
 
-      if ( end != n_points - 1 )
+      if ( end0 != n_points - 1 )
         goto Bad;
 
       /* XXX: check the tags array */
@@ -388,7 +387,7 @@
     }
 
   Bad:
-    return FT_THROW( Invalid_Argument );
+    return FT_THROW( Invalid_Outline );
   }
 
 
@@ -550,10 +549,12 @@
     if ( !outline )
       return;
 
-    first = 0;
-
+    last = -1;
     for ( n = 0; n < outline->n_contours; n++ )
     {
+      /* keep the first contour point as is and swap points around it */
+      /* to guarantee that the cubic arches stay valid after reverse  */
+      first = last + 2;
       last  = outline->contours[n];
 
       /* reverse point table */
@@ -591,8 +592,6 @@
           q--;
         }
       }
-
-      first = last + 1;
     }
 
     outline->flags ^= FT_OUTLINE_REVERSE_FILL;
@@ -941,7 +940,7 @@
 
     points = outline->points;
 
-    first = 0;
+    last = -1;
     for ( c = 0; c < outline->n_contours; c++ )
     {
       FT_Vector  in, out, anchor, shift;
@@ -949,8 +948,9 @@
       FT_Int     i, j, k;
 
 
-      l_in = 0;
-      last = outline->contours[c];
+      first = last + 1;
+      last  = outline->contours[c];
+      l_in  = 0;
 
       /* pacify compiler */
       in.x = in.y = anchor.x = anchor.y = 0;
@@ -1037,8 +1037,6 @@
         in   = out;
         l_in = l_out;
       }
-
-      first = last + 1;
     }
 
     return FT_Err_Ok;
@@ -1054,7 +1052,7 @@
     FT_Int      xshift, yshift;
     FT_Vector*  points;
     FT_Vector   v_prev, v_cur;
-    FT_Int      c, n, first;
+    FT_Int      c, n, first, last;
     FT_Pos      area = 0;
 
 
@@ -1086,11 +1084,11 @@
 
     points = outline->points;
 
-    first = 0;
+    last = -1;
     for ( c = 0; c < outline->n_contours; c++ )
     {
-      FT_Int  last = outline->contours[c];
-
+      first = last + 1;
+      last  = outline->contours[c];
 
       v_prev.x = points[last].x >> xshift;
       v_prev.y = points[last].y >> yshift;
@@ -1106,8 +1104,6 @@
 
         v_prev = v_cur;
       }
-
-      first = last + 1;
     }
 
     if ( area > 0 )
diff --git a/src/base/ftstream.c b/src/base/ftstream.c
index 05c5637..64826ac 100644
--- a/src/base/ftstream.c
+++ b/src/base/ftstream.c
@@ -141,7 +141,9 @@
       if ( read_bytes > count )
         read_bytes = count;
 
-      FT_MEM_COPY( buffer, stream->base + pos, read_bytes );
+      /* Allow "reading" zero bytes without UB even if buffer is NULL */
+      if ( count )
+        FT_MEM_COPY( buffer, stream->base + pos, read_bytes );
     }
 
     stream->pos = pos + read_bytes;
@@ -178,7 +180,9 @@
       if ( read_bytes > count )
         read_bytes = count;
 
-      FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes );
+      /* Allow "reading" zero bytes without UB even if buffer is NULL */
+      if ( count )
+        FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes );
     }
 
     stream->pos += read_bytes;
diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c
index db358e7..92f1e43 100644
--- a/src/base/ftstroke.c
+++ b/src/base/ftstroke.c
@@ -2055,7 +2055,9 @@
     FT_Error    error;
 
     FT_Int      n;         /* index of contour in outline     */
-    FT_UInt     first;     /* index of first point in contour */
+    FT_Int      first;     /* index of first point in contour */
+    FT_Int      last;      /* index of last point in contour  */
+
     FT_Int      tag;       /* current point's state           */
 
 
@@ -2067,22 +2069,17 @@
 
     FT_Stroker_Rewind( stroker );
 
-    first = 0;
-
+    last = -1;
     for ( n = 0; n < outline->n_contours; n++ )
     {
-      FT_UInt  last;  /* index of last point in contour */
-
-
-      last  = (FT_UInt)outline->contours[n];
-      limit = outline->points + last;
+      first = last + 1;
+      last  = outline->contours[n];
 
       /* skip empty points; we don't stroke these */
       if ( last <= first )
-      {
-        first = last + 1;
         continue;
-      }
+
+      limit = outline->points + last;
 
       v_start = outline->points[first];
       v_last  = outline->points[last];
@@ -2231,8 +2228,6 @@
         if ( error )
           goto Exit;
       }
-
-      first = last + 1;
     }
 
     return FT_Err_Ok;
diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c
index 6ec25e1..f32edd3 100644
--- a/src/base/ftsynth.c
+++ b/src/base/ftsynth.c
@@ -98,8 +98,17 @@
   FT_EXPORT_DEF( void )
   FT_GlyphSlot_Embolden( FT_GlyphSlot  slot )
   {
+    FT_GlyphSlot_AdjustWeight( slot, 0x0AAA, 0x0AAA );
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FT_GlyphSlot_AdjustWeight( FT_GlyphSlot  slot,
+                             FT_Fixed      xdelta,
+                             FT_Fixed      ydelta )
+  {
     FT_Library  library;
-    FT_Face     face;
+    FT_Size     size;
     FT_Error    error;
     FT_Pos      xstr, ystr;
 
@@ -108,16 +117,15 @@
       return;
 
     library = slot->library;
-    face    = slot->face;
+    size    = slot->face->size;
 
     if ( slot->format != FT_GLYPH_FORMAT_OUTLINE &&
          slot->format != FT_GLYPH_FORMAT_BITMAP  )
       return;
 
-    /* some reasonable strength */
-    xstr = FT_MulFix( face->units_per_EM,
-                      face->size->metrics.y_scale ) / 24;
-    ystr = xstr;
+    /* express deltas in pixels in 26.6 format */
+    xstr = (FT_Pos)size->metrics.x_ppem * xdelta / 1024;
+    ystr = (FT_Pos)size->metrics.y_ppem * ydelta / 1024;
 
     if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
       FT_Outline_EmboldenXY( &slot->outline, xstr, ystr );
diff --git a/src/base/ftsystem.c b/src/base/ftsystem.c
index fcd289d..61c99e3 100644
--- a/src/base/ftsystem.c
+++ b/src/base/ftsystem.c
@@ -206,7 +206,7 @@
    *     The number of bytes to read from the stream.
    *
    * @Return:
-   *   The number of bytes actually read.  If `count' is zero (this is,
+   *   The number of bytes actually read.  If `count' is zero (that is,
    *   the function is used for seeking), a non-zero return value
    *   indicates an error.
    */
@@ -219,7 +219,7 @@
     FT_FILE*  file;
 
 
-    if ( !count && offset > stream->size )
+    if ( offset > stream->size && !count )
       return 1;
 
     file = STREAM_FILE( stream );
@@ -227,6 +227,11 @@
     if ( stream->pos != offset )
       ft_fseek( file, (long)offset, SEEK_SET );
 
+    /* Avoid calling `fread` with `buffer=NULL` and `count=0`, */
+    /* which is undefined behaviour.                           */
+    if ( !count )
+      return 0;
+
     return (unsigned long)ft_fread( buffer, 1, count, file );
   }
 
diff --git a/src/base/ftver.rc b/src/base/ftver.rc
index f113cb8..137a633 100644
--- a/src/base/ftver.rc
+++ b/src/base/ftver.rc
@@ -18,8 +18,8 @@
 
 #include<windows.h>
 
-#define FT_VERSION      2,13,0,0
-#define FT_VERSION_STR  "2.13.0"
+#define FT_VERSION      2,13,2,0
+#define FT_VERSION_STR  "2.13.2"
 
 VS_VERSION_INFO      VERSIONINFO
 FILEVERSION          FT_VERSION
diff --git a/src/bdf/bdf.h b/src/bdf/bdf.h
index 5acbd5f..e2cb52c 100644
--- a/src/bdf/bdf.h
+++ b/src/bdf/bdf.h
@@ -240,10 +240,6 @@
   bdf_free_font( bdf_font_t*  font );
 
   FT_LOCAL( bdf_property_t * )
-  bdf_get_property( char*        name,
-                    bdf_font_t*  font );
-
-  FT_LOCAL( bdf_property_t * )
   bdf_get_font_property( bdf_font_t*  font,
                          const char*  name );
 
diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c
index d7e8e0e..e02a160 100644
--- a/src/bdf/bdfdrivr.c
+++ b/src/bdf/bdfdrivr.c
@@ -311,9 +311,9 @@
 
 
   FT_CALLBACK_DEF( void )
-  BDF_Face_Done( FT_Face  bdfface )         /* BDF_Face */
+  BDF_Face_Done( FT_Face  face )         /* BDF_Face */
   {
-    BDF_Face   face = (BDF_Face)bdfface;
+    BDF_Face   bdfface = (BDF_Face)face;
     FT_Memory  memory;
 
 
@@ -322,31 +322,31 @@
 
     memory = FT_FACE_MEMORY( face );
 
-    bdf_free_font( face->bdffont );
+    bdf_free_font( bdfface->bdffont );
 
-    FT_FREE( face->en_table );
+    FT_FREE( bdfface->en_table );
 
-    FT_FREE( face->charset_encoding );
-    FT_FREE( face->charset_registry );
-    FT_FREE( bdfface->family_name );
-    FT_FREE( bdfface->style_name );
+    FT_FREE( bdfface->charset_encoding );
+    FT_FREE( bdfface->charset_registry );
+    FT_FREE( face->family_name );
+    FT_FREE( face->style_name );
 
-    FT_FREE( bdfface->available_sizes );
+    FT_FREE( face->available_sizes );
 
-    FT_FREE( face->bdffont );
+    FT_FREE( bdfface->bdffont );
   }
 
 
   FT_CALLBACK_DEF( FT_Error )
   BDF_Face_Init( FT_Stream      stream,
-                 FT_Face        bdfface,        /* BDF_Face */
+                 FT_Face        face,        /* BDF_Face */
                  FT_Int         face_index,
                  FT_Int         num_params,
                  FT_Parameter*  params )
   {
-    FT_Error       error  = FT_Err_Ok;
-    BDF_Face       face   = (BDF_Face)bdfface;
-    FT_Memory      memory = FT_FACE_MEMORY( face );
+    FT_Error       error   = FT_Err_Ok;
+    BDF_Face       bdfface = (BDF_Face)face;
+    FT_Memory      memory  = FT_FACE_MEMORY( face );
 
     bdf_font_t*    font = NULL;
     bdf_options_t  options;
@@ -375,7 +375,7 @@
       goto Exit;
 
     /* we have a bdf font: let's construct the face object */
-    face->bdffont = font;
+    bdfface->bdffont = font;
 
     /* BDF cannot have multiple faces in a single font file.
      * XXX: non-zero face_index is already invalid argument, but
@@ -386,7 +386,7 @@
     if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 )
     {
       FT_ERROR(( "BDF_Face_Init: invalid face index\n" ));
-      BDF_Face_Done( bdfface );
+      BDF_Face_Done( face );
       return FT_THROW( Invalid_Argument );
     }
 
@@ -401,18 +401,18 @@
                   font->unencoded_size,
                   font->unencoded_used ));
 
-      bdfface->num_faces  = 1;
-      bdfface->face_index = 0;
+      face->num_faces  = 1;
+      face->face_index = 0;
 
-      bdfface->face_flags |= FT_FACE_FLAG_FIXED_SIZES |
-                             FT_FACE_FLAG_HORIZONTAL;
+      face->face_flags |= FT_FACE_FLAG_FIXED_SIZES |
+                          FT_FACE_FLAG_HORIZONTAL;
 
       prop = bdf_get_font_property( font, "SPACING" );
       if ( prop && prop->format == BDF_ATOM                             &&
            prop->value.atom                                             &&
            ( *(prop->value.atom) == 'M' || *(prop->value.atom) == 'm' ||
              *(prop->value.atom) == 'C' || *(prop->value.atom) == 'c' ) )
-        bdfface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
+        face->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
 
       /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL   */
       /* FZ XXX: I need a font to implement this */
@@ -420,26 +420,27 @@
       prop = bdf_get_font_property( font, "FAMILY_NAME" );
       if ( prop && prop->value.atom )
       {
-        if ( FT_STRDUP( bdfface->family_name, prop->value.atom ) )
+        if ( FT_STRDUP( face->family_name, prop->value.atom ) )
           goto Exit;
       }
       else
-        bdfface->family_name = NULL;
+        face->family_name = NULL;
 
-      if ( FT_SET_ERROR( bdf_interpret_style( face ) ) )
+      if ( FT_SET_ERROR( bdf_interpret_style( bdfface ) ) )
         goto Exit;
 
       /* the number of glyphs (with one slot for the undefined glyph */
       /* at position 0 and all unencoded glyphs)                     */
-      bdfface->num_glyphs = (FT_Long)( font->glyphs_size + 1 );
+      face->num_glyphs = (FT_Long)( font->glyphs_size + 1 );
 
-      bdfface->num_fixed_sizes = 1;
-      if ( FT_NEW( bdfface->available_sizes ) )
+      face->num_fixed_sizes = 1;
+      if ( FT_NEW( face->available_sizes ) )
         goto Exit;
 
       {
-        FT_Bitmap_Size*  bsize = bdfface->available_sizes;
-        FT_Short         resolution_x = 0, resolution_y = 0;
+        FT_Bitmap_Size*  bsize        = face->available_sizes;
+        FT_Short         resolution_x = 0;
+        FT_Short         resolution_y = 0;
         long             value;
 
 
@@ -598,20 +599,20 @@
         unsigned long  n;
 
 
-        if ( FT_QNEW_ARRAY( face->en_table, font->glyphs_size ) )
+        if ( FT_QNEW_ARRAY( bdfface->en_table, font->glyphs_size ) )
           goto Exit;
 
-        face->default_glyph = 0;
+        bdfface->default_glyph = 0;
         for ( n = 0; n < font->glyphs_size; n++ )
         {
-          (face->en_table[n]).enc = cur[n].encoding;
+          (bdfface->en_table[n]).enc = cur[n].encoding;
           FT_TRACE4(( "  idx %ld, val 0x%lX\n", n, cur[n].encoding ));
-          (face->en_table[n]).glyph = (FT_UShort)n;
+          (bdfface->en_table[n]).glyph = (FT_UShort)n;
 
           if ( cur[n].encoding == font->default_char )
           {
             if ( n < FT_UINT_MAX )
-              face->default_glyph = (FT_UInt)n;
+              bdfface->default_glyph = (FT_UInt)n;
             else
               FT_TRACE1(( "BDF_Face_Init:"
                           " idx %ld is too large for this system\n", n ));
@@ -639,27 +640,27 @@
             const char*  s;
 
 
-            if ( FT_STRDUP( face->charset_encoding,
+            if ( FT_STRDUP( bdfface->charset_encoding,
                             charset_encoding->value.atom ) ||
-                 FT_STRDUP( face->charset_registry,
+                 FT_STRDUP( bdfface->charset_registry,
                             charset_registry->value.atom ) )
               goto Exit;
 
             /* Uh, oh, compare first letters manually to avoid dependency */
             /* on locales.                                                */
-            s = face->charset_registry;
+            s = bdfface->charset_registry;
             if ( ( s[0] == 'i' || s[0] == 'I' ) &&
                  ( s[1] == 's' || s[1] == 'S' ) &&
                  ( s[2] == 'o' || s[2] == 'O' ) )
             {
               s += 3;
-              if ( !ft_strcmp( s, "10646" )                      ||
-                   ( !ft_strcmp( s, "8859" ) &&
-                     !ft_strcmp( face->charset_encoding, "1" ) ) )
+              if ( !ft_strcmp( s, "10646" )                         ||
+                   ( !ft_strcmp( s, "8859" )                      &&
+                     !ft_strcmp( bdfface->charset_encoding, "1" ) ) )
                 unicode_charmap = 1;
               /* another name for ASCII */
-              else if ( !ft_strcmp( s, "646.1991" )                 &&
-                        !ft_strcmp( face->charset_encoding, "IRV" ) )
+              else if ( !ft_strcmp( s, "646.1991" )                    &&
+                        !ft_strcmp( bdfface->charset_encoding, "IRV" ) )
                 unicode_charmap = 1;
             }
 
@@ -667,7 +668,7 @@
               FT_CharMapRec  charmap;
 
 
-              charmap.face        = FT_FACE( face );
+              charmap.face        = face;
               charmap.encoding    = FT_ENCODING_NONE;
               /* initial platform/encoding should indicate unset status? */
               charmap.platform_id = TT_PLATFORM_APPLE_UNICODE;
@@ -693,7 +694,7 @@
           FT_CharMapRec  charmap;
 
 
-          charmap.face        = FT_FACE( face );
+          charmap.face        = face;
           charmap.encoding    = FT_ENCODING_ADOBE_STANDARD;
           charmap.platform_id = TT_PLATFORM_ADOBE;
           charmap.encoding_id = TT_ADOBE_ID_STANDARD;
@@ -701,8 +702,8 @@
           error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL );
 
           /* Select default charmap */
-          if ( bdfface->num_charmaps )
-            bdfface->charmap = bdfface->charmaps[0];
+          if ( face->num_charmaps )
+            face->charmap = face->charmaps[0];
         }
       }
     }
@@ -711,7 +712,7 @@
     return error;
 
   Fail:
-    BDF_Face_Done( bdfface );
+    BDF_Face_Done( face );
     return FT_THROW( Unknown_File_Format );
   }
 
@@ -868,17 +869,18 @@
   *
   */
 
-  static FT_Error
-  bdf_get_bdf_property( BDF_Face          face,
+  FT_CALLBACK_DEF( FT_Error )
+  bdf_get_bdf_property( FT_Face           face,       /* BDF_Face */
                         const char*       prop_name,
                         BDF_PropertyRec  *aproperty )
   {
+    BDF_Face         bdfface = (BDF_Face)face;
     bdf_property_t*  prop;
 
 
-    FT_ASSERT( face && face->bdffont );
+    FT_ASSERT( bdfface && bdfface->bdffont );
 
-    prop = bdf_get_font_property( face->bdffont, prop_name );
+    prop = bdf_get_font_property( bdfface->bdffont, prop_name );
     if ( prop )
     {
       switch ( prop->format )
@@ -921,13 +923,16 @@
   }
 
 
-  static FT_Error
-  bdf_get_charset_id( BDF_Face      face,
+  FT_CALLBACK_DEF( FT_Error )
+  bdf_get_charset_id( FT_Face       face,               /* BDF_Face */
                       const char*  *acharset_encoding,
                       const char*  *acharset_registry )
   {
-    *acharset_encoding = face->charset_encoding;
-    *acharset_registry = face->charset_registry;
+    BDF_Face  bdfface = (BDF_Face)face;
+
+
+    *acharset_encoding = bdfface->charset_encoding;
+    *acharset_registry = bdfface->charset_registry;
 
     return 0;
   }
@@ -964,7 +969,6 @@
   }
 
 
-
   FT_CALLBACK_TABLE_DEF
   const FT_Driver_ClassRec  bdf_driver_class =
   {
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 2224698..0fa7e0a 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -51,6 +51,9 @@
 #define FT_COMPONENT  bdflib
 
 
+#define BUFSIZE  128
+
+
   /**************************************************************************
    *
    * Default BDF font options.
@@ -378,7 +381,7 @@
     *alen = 0;
 
     if ( list == NULL || list->used == 0 )
-      return 0;
+      return NULL;
 
     dp = list->field[0];
     for ( i = j = 0; i < list->used; i++ )
@@ -887,18 +890,18 @@
   }
 
 
-  FT_LOCAL_DEF( bdf_property_t* )
-  bdf_get_property( char*        name,
+  static bdf_property_t*
+  bdf_get_property( const char*  name,
                     bdf_font_t*  font )
   {
     size_t*  propid;
 
 
     if ( name == NULL || *name == 0 )
-      return 0;
+      return NULL;
 
     if ( ( propid = ft_hash_str_lookup( name, &(font->proptbl) ) ) == NULL )
-      return 0;
+      return NULL;
 
     if ( *propid >= num_bdf_properties_ )
       return font->user_props + ( *propid - num_bdf_properties_ );
@@ -944,7 +947,7 @@
 
   static FT_Error
   bdf_add_comment_( bdf_font_t*    font,
-                    char*          comment,
+                    const char*    comment,
                     unsigned long  len )
   {
     char*      cp;
@@ -1053,27 +1056,24 @@
     bdf_property_t*  p;
 
 
-    *name = sp = ep = line;
+    sp = ep = line;
 
     while ( *ep && *ep != ' ' && *ep != '\t' )
       ep++;
 
-    hold = -1;
-    if ( *ep )
-    {
-      hold = *ep;
-      *ep  = 0;
-    }
+    hold = *ep;
+    *ep  = '\0';
 
     p = bdf_get_property( sp, font );
 
-    /* Restore the character that was saved before any return can happen. */
-    if ( hold != -1 )
-      *ep = (char)hold;
-
     /* If the property exists and is not an atom, just return here. */
     if ( p && p->format != BDF_ATOM )
+    {
+      *ep = (char)hold;  /* Undo NUL-termination. */
       return 0;
+    }
+
+    *name = sp;
 
     /* The property is an atom.  Trim all leading and trailing whitespace */
     /* and double quotes for the atom value.                              */
@@ -1081,25 +1081,26 @@
     ep = line + linelen;
 
     /* Trim the leading whitespace if it exists. */
-    if ( *sp )
-      *sp++ = 0;
-    while ( *sp                           &&
-            ( *sp == ' ' || *sp == '\t' ) )
-      sp++;
+    if ( sp < ep )
+      do
+         sp++;
+      while ( *sp == ' ' || *sp == '\t' );
 
     /* Trim the leading double quote if it exists. */
     if ( *sp == '"' )
       sp++;
+
     *value = sp;
 
     /* Trim the trailing whitespace if it exists. */
-    while ( ep > sp                                       &&
-            ( *( ep - 1 ) == ' ' || *( ep - 1 ) == '\t' ) )
-      *--ep = 0;
+    if ( sp < ep )
+      do
+        *ep-- = '\0';
+      while ( *ep == ' ' || *ep  == '\t' );
 
     /* Trim the trailing double quote if it exists. */
-    if ( ep > sp && *( ep - 1 ) == '"' )
-      *--ep = 0;
+    if ( *ep  == '"' )
+      *ep = '\0';
 
     return 1;
   }
@@ -1775,7 +1776,7 @@
     bdf_parse_t_*      p;
     char*              name;
     char*              value;
-    char               nbuf[128];
+    char               nbuf[BUFSIZE];
     FT_Error           error = FT_Err_Ok;
 
     FT_UNUSED( lineno );
@@ -1796,7 +1797,7 @@
       if ( bdf_get_font_property( p->font, "FONT_ASCENT" ) == 0 )
       {
         p->font->font_ascent = p->font->bbx.ascent;
-        ft_sprintf( nbuf, "%hd", p->font->bbx.ascent );
+        ft_snprintf( nbuf, BUFSIZE, "%hd", p->font->bbx.ascent );
         error = bdf_add_property_( p->font, "FONT_ASCENT",
                                    nbuf, lineno );
         if ( error )
@@ -1808,7 +1809,7 @@
       if ( bdf_get_font_property( p->font, "FONT_DESCENT" ) == 0 )
       {
         p->font->font_descent = p->font->bbx.descent;
-        ft_sprintf( nbuf, "%hd", p->font->bbx.descent );
+        ft_snprintf( nbuf, BUFSIZE, "%hd", p->font->bbx.descent );
         error = bdf_add_property_( p->font, "FONT_DESCENT",
                                    nbuf, lineno );
         if ( error )
@@ -2116,7 +2117,7 @@
     /* Check for the CHARS field -- font properties are optional */
     if ( _bdf_strncmp( line, "CHARS", 5 ) == 0 )
     {
-      char  nbuf[128];
+      char  nbuf[BUFSIZE];
 
 
       if ( !( p->flags & BDF_FONT_BBX_ ) )
@@ -2130,7 +2131,7 @@
       /* Add the two standard X11 properties which are required */
       /* for compiling fonts.                                   */
       p->font->font_ascent = p->font->bbx.ascent;
-      ft_sprintf( nbuf, "%hd", p->font->bbx.ascent );
+      ft_snprintf( nbuf, BUFSIZE, "%hd", p->font->bbx.ascent );
       error = bdf_add_property_( p->font, "FONT_ASCENT",
                                  nbuf, lineno );
       if ( error )
@@ -2138,7 +2139,7 @@
       FT_TRACE2(( "bdf_parse_properties_: " ACMSG1, p->font->bbx.ascent ));
 
       p->font->font_descent = p->font->bbx.descent;
-      ft_sprintf( nbuf, "%hd", p->font->bbx.descent );
+      ft_snprintf( nbuf, BUFSIZE, "%hd", p->font->bbx.descent );
       error = bdf_add_property_( p->font, "FONT_DESCENT",
                                  nbuf, lineno );
       if ( error )
diff --git a/src/bzip2/ftbzip2.c b/src/bzip2/ftbzip2.c
index 6cf1067..ad342bd 100644
--- a/src/bzip2/ftbzip2.c
+++ b/src/bzip2/ftbzip2.c
@@ -62,10 +62,12 @@
 
 
   static void*
-  ft_bzip2_alloc( FT_Memory  memory,
-                  int        items,
-                  int        size )
+  ft_bzip2_alloc( void*  memory_,  /* FT_Memory */
+                  int    items,
+                  int    size )
   {
+    FT_Memory  memory = (FT_Memory)memory_;
+
     FT_ULong    sz = (FT_ULong)size * (FT_ULong)items;
     FT_Error    error;
     FT_Pointer  p  = NULL;
@@ -77,9 +79,12 @@
 
 
   static void
-  ft_bzip2_free( FT_Memory  memory,
-                 void*      address )
+  ft_bzip2_free( void*  memory_,   /* FT_Memory */
+                 void*  address )
   {
+    FT_Memory  memory = (FT_Memory)memory_;
+
+
     FT_MEM_FREE( address );
   }
 
@@ -170,8 +175,8 @@
     }
 
     /* initialize bzlib */
-    bzstream->bzalloc = (alloc_func)ft_bzip2_alloc;
-    bzstream->bzfree  = (free_func) ft_bzip2_free;
+    bzstream->bzalloc = ft_bzip2_alloc;
+    bzstream->bzfree  = ft_bzip2_free;
     bzstream->opaque  = zip->memory;
 
     bzstream->avail_in = 0;
diff --git a/src/cache/ftcbasic.c b/src/cache/ftcbasic.c
index 4c6d41b..24a56c8 100644
--- a/src/cache/ftcbasic.c
+++ b/src/cache/ftcbasic.c
@@ -337,7 +337,7 @@
 #if 1  /* inlining is about 50% faster! */
     FTC_GCACHE_LOOKUP_CMP( cache,
                            ftc_basic_family_compare,
-                           FTC_GNode_Compare,
+                           ftc_gnode_compare,
                            hash, gindex,
                            &query,
                            node,
@@ -411,7 +411,7 @@
 
     FTC_GCACHE_LOOKUP_CMP( cache,
                            ftc_basic_family_compare,
-                           FTC_GNode_Compare,
+                           ftc_gnode_compare,
                            hash, gindex,
                            &query,
                            node,
@@ -537,7 +537,7 @@
 #if 1  /* inlining is about 50% faster! */
     FTC_GCACHE_LOOKUP_CMP( cache,
                            ftc_basic_family_compare,
-                           FTC_SNode_Compare,
+                           ftc_snode_compare,
                            hash, gindex,
                            &query,
                            node,
@@ -613,7 +613,7 @@
 
     FTC_GCACHE_LOOKUP_CMP( cache,
                            ftc_basic_family_compare,
-                           FTC_SNode_Compare,
+                           ftc_snode_compare,
                            hash, gindex,
                            &query,
                            node,
diff --git a/src/cache/ftccache.c b/src/cache/ftccache.c
index d54e68c..e069855 100644
--- a/src/cache/ftccache.c
+++ b/src/cache/ftccache.c
@@ -94,8 +94,8 @@
 
 
     idx = hash & cache->mask;
-    if ( idx < cache->p )
-      idx = hash & ( 2 * cache->mask + 1 );
+    if ( idx >= cache->p )
+      idx = hash & ( cache->mask >> 1 );
 
     return cache->buckets + idx;
   }
@@ -113,9 +113,9 @@
     for (;;)
     {
       FTC_Node  node, *pnode;
-      FT_UFast  p     = cache->p;
-      FT_UFast  mask  = cache->mask;
-      FT_UFast  count = mask + p + 1;    /* number of buckets */
+      FT_UFast  p    = cache->p;
+      FT_UFast  size = cache->mask + 1;  /* available size */
+      FT_UFast  half = size >> 1;
 
 
       /* do we need to expand the buckets array? */
@@ -127,20 +127,22 @@
         /* try to expand the buckets array _before_ splitting
          * the bucket lists
          */
-        if ( p >= mask )
+        if ( p == size )
         {
           FT_Memory  memory = cache->memory;
           FT_Error   error;
 
 
           /* if we can't expand the array, leave immediately */
-          if ( FT_RENEW_ARRAY( cache->buckets,
-                               ( mask + 1 ) * 2, ( mask + 1 ) * 4 ) )
+          if ( FT_QRENEW_ARRAY( cache->buckets, size, size * 2 ) )
             break;
+
+          cache->mask = 2 * size - 1;
+          half        = size;
         }
 
-        /* split a single bucket */
-        pnode = cache->buckets + p;
+        /* the bucket to split */
+        pnode = cache->buckets + p - half;
 
         for (;;)
         {
@@ -148,7 +150,7 @@
           if ( !node )
             break;
 
-          if ( node->hash & ( mask + 1 ) )
+          if ( node->hash & half )
           {
             *pnode     = node->link;
             node->link = new_list;
@@ -158,56 +160,50 @@
             pnode = &node->link;
         }
 
-        cache->buckets[p + mask + 1] = new_list;
+        cache->buckets[p] = new_list;
 
         cache->slack += FTC_HASH_MAX_LOAD;
+        cache->p      = p + 1;
 
-        if ( p >= mask )
-        {
-          cache->mask = 2 * mask + 1;
-          cache->p    = 0;
-        }
-        else
-          cache->p = p + 1;
+        FT_TRACE2(( "ftc_cache_resize: cache %u increased to %u hashes\n",
+                    cache->index, cache->p ));
       }
 
       /* do we need to shrink the buckets array? */
-      else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD )
+      else if ( cache->slack > (FT_Long)p * FTC_HASH_SUB_LOAD )
       {
-        FT_UFast   old_index = p + mask;
-        FTC_Node*  pold;
+        FTC_Node  old_list = cache->buckets[--p];
 
 
-        if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE )
+        if ( p < FTC_HASH_INITIAL_SIZE )
           break;
 
-        if ( p == 0 )
+        if ( p == half )
         {
           FT_Memory  memory = cache->memory;
           FT_Error   error;
 
 
           /* if we can't shrink the array, leave immediately */
-          if ( FT_QRENEW_ARRAY( cache->buckets,
-                               ( mask + 1 ) * 2, mask + 1 ) )
+          if ( FT_QRENEW_ARRAY( cache->buckets, size, half ) )
             break;
 
-          cache->mask >>= 1;
-          p             = cache->mask;
+          cache->mask = half - 1;
         }
-        else
-          p--;
 
-        pnode = cache->buckets + p;
+        /* the bucket to merge */
+        pnode = cache->buckets + p - half;
+
         while ( *pnode )
           pnode = &(*pnode)->link;
 
-        pold   = cache->buckets + old_index;
-        *pnode = *pold;
-        *pold  = NULL;
+        *pnode = old_list;
 
         cache->slack -= FTC_HASH_MAX_LOAD;
         cache->p      = p;
+
+        FT_TRACE2(( "ftc_cache_resize: cache %u decreased to %u hashes\n",
+                    cache->index, cache->p ));
       }
 
       /* otherwise, the hash table is balanced */
@@ -239,7 +235,7 @@
       if ( node == node0 )
         break;
 
-      pnode = &(*pnode)->link;
+      pnode = &node->link;
     }
 
     *pnode      = node0->link;
@@ -323,40 +319,41 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  FTC_Cache_Init( FTC_Cache  cache )
-  {
-    return ftc_cache_init( cache );
-  }
-
-
-  FT_LOCAL_DEF( FT_Error )
   ftc_cache_init( FTC_Cache  cache )
   {
     FT_Memory  memory = cache->memory;
     FT_Error   error;
 
 
-    cache->p     = 0;
+    cache->p     = FTC_HASH_INITIAL_SIZE;
     cache->mask  = FTC_HASH_INITIAL_SIZE - 1;
     cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD;
 
-    FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 );
+    FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE );
     return error;
   }
 
 
-  static void
-  FTC_Cache_Clear( FTC_Cache  cache )
+  FT_LOCAL_DEF( FT_Error )
+  FTC_Cache_Init( FTC_Cache  cache )
   {
-    if ( cache && cache->buckets )
+    return ftc_cache_init( cache );
+  }
+
+
+  FT_LOCAL_DEF( void )
+  ftc_cache_done( FTC_Cache  cache )
+  {
+    FT_Memory  memory = cache->memory;
+
+
+    if ( cache->buckets )
     {
       FTC_Manager  manager = cache->manager;
+      FT_UFast     count   = cache->p;
       FT_UFast     i;
-      FT_UFast     count;
 
 
-      count = cache->p + cache->mask + 1;
-
       for ( i = 0; i < count; i++ )
       {
         FTC_Node  node = cache->buckets[i], next;
@@ -376,30 +373,14 @@
           cache->clazz.node_free( node, cache );
           node = next;
         }
-        cache->buckets[i] = NULL;
       }
-      ftc_cache_resize( cache );
     }
-  }
 
+    FT_FREE( cache->buckets );
 
-  FT_LOCAL_DEF( void )
-  ftc_cache_done( FTC_Cache  cache )
-  {
-    if ( cache->memory )
-    {
-      FT_Memory  memory = cache->memory;
-
-
-      FTC_Cache_Clear( cache );
-
-      FT_FREE( cache->buckets );
-      cache->mask  = 0;
-      cache->p     = 0;
-      cache->slack = 0;
-
-      cache->memory = NULL;
-    }
+    cache->p     = 0;
+    cache->mask  = 0;
+    cache->slack = 0;
   }
 
 
@@ -562,12 +543,12 @@
   FTC_Cache_RemoveFaceID( FTC_Cache   cache,
                           FTC_FaceID  face_id )
   {
-    FT_UFast     i, count;
     FTC_Manager  manager = cache->manager;
     FTC_Node     frees   = NULL;
+    FT_UFast     count   = cache->p;
+    FT_UFast     i;
 
 
-    count = cache->p + cache->mask + 1;
     for ( i = 0; i < count; i++ )
     {
       FTC_Node*  pnode = cache->buckets + i;
diff --git a/src/cache/ftccache.h b/src/cache/ftccache.h
index 23bcb65..850d255 100644
--- a/src/cache/ftccache.h
+++ b/src/cache/ftccache.h
@@ -72,11 +72,12 @@
 #define FTC_NODE_NEXT( x )  FTC_NODE( (x)->mru.next )
 #define FTC_NODE_PREV( x )  FTC_NODE( (x)->mru.prev )
 
+  /* address the hash table entries */
 #ifdef FTC_INLINE
-#define FTC_NODE_TOP_FOR_HASH( cache, hash )                      \
-        ( ( cache )->buckets +                                    \
-            ( ( ( ( hash ) &   ( cache )->mask ) < ( cache )->p ) \
-              ? ( ( hash ) & ( ( cache )->mask * 2 + 1 ) )        \
+#define FTC_NODE_TOP_FOR_HASH( cache, hash )                       \
+        ( ( cache )->buckets +                                     \
+            ( ( ( ( hash ) &   ( cache )->mask ) >= ( cache )->p ) \
+              ? ( ( hash ) & ( ( cache )->mask >> 1 ) )            \
               : ( ( hash ) &   ( cache )->mask ) ) )
 #else
   FT_LOCAL( FTC_Node* )
@@ -139,11 +140,13 @@
   } FTC_CacheClassRec;
 
 
-  /* each cache really implements a dynamic hash table to manage its nodes */
+  /* each cache really implements a hash table to manage its nodes    */
+  /* the number of the table entries (buckets) can change dynamically */
+  /* each bucket contains a linked lists of nodes for a given hash    */
   typedef struct  FTC_CacheRec_
   {
-    FT_UFast           p;
-    FT_UFast           mask;
+    FT_UFast           p;           /* hash table counter     */
+    FT_UFast           mask;        /* hash table index range */
     FT_Long            slack;
     FTC_Node*          buckets;
 
diff --git a/src/cache/ftcglyph.c b/src/cache/ftcglyph.c
index b3fb2f2..d344733 100644
--- a/src/cache/ftcglyph.c
+++ b/src/cache/ftcglyph.c
@@ -79,20 +79,6 @@
   }
 
 
-#ifdef FTC_INLINE
-
-  FT_LOCAL_DEF( FT_Bool )
-  FTC_GNode_Compare( FTC_GNode   gnode,
-                     FTC_GQuery  gquery,
-                     FTC_Cache   cache,
-                     FT_Bool*    list_changed )
-  {
-    return ftc_gnode_compare( FTC_NODE( gnode ), gquery,
-                              cache, list_changed );
-  }
-
-#endif
-
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -115,22 +101,22 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  ftc_gcache_init( FTC_Cache  ftccache )
+  ftc_gcache_init( FTC_Cache  cache )
   {
-    FTC_GCache  cache = (FTC_GCache)ftccache;
+    FTC_GCache  gcache = (FTC_GCache)cache;
     FT_Error    error;
 
 
-    error = FTC_Cache_Init( FTC_CACHE( cache ) );
+    error = FTC_Cache_Init( cache );
     if ( !error )
     {
-      FTC_GCacheClass   clazz = (FTC_GCacheClass)FTC_CACHE( cache )->org_class;
+      FTC_GCacheClass   clazz = (FTC_GCacheClass)cache->org_class;
 
-      FTC_MruList_Init( &cache->families,
+      FTC_MruList_Init( &gcache->families,
                         clazz->family_class,
                         0,  /* no maximum here! */
                         cache,
-                        FTC_CACHE( cache )->memory );
+                        cache->memory );
     }
 
     return error;
@@ -140,31 +126,31 @@
 #if 0
 
   FT_LOCAL_DEF( FT_Error )
-  FTC_GCache_Init( FTC_GCache  cache )
+  FTC_GCache_Init( FTC_GCache  gcache )
   {
-    return ftc_gcache_init( FTC_CACHE( cache ) );
+    return ftc_gcache_init( FTC_CACHE( gcache ) );
   }
 
 #endif /* 0 */
 
 
   FT_LOCAL_DEF( void )
-  ftc_gcache_done( FTC_Cache  ftccache )
+  ftc_gcache_done( FTC_Cache  cache )
   {
-    FTC_GCache  cache = (FTC_GCache)ftccache;
+    FTC_GCache  gcache = (FTC_GCache)cache;
 
 
-    FTC_Cache_Done( (FTC_Cache)cache );
-    FTC_MruList_Done( &cache->families );
+    FTC_Cache_Done( cache );
+    FTC_MruList_Done( &gcache->families );
   }
 
 
 #if 0
 
   FT_LOCAL_DEF( void )
-  FTC_GCache_Done( FTC_GCache  cache )
+  FTC_GCache_Done( FTC_GCache  gcache )
   {
-    ftc_gcache_done( FTC_CACHE( cache ) );
+    ftc_gcache_done( FTC_CACHE( gcache ) );
   }
 
 #endif /* 0 */
@@ -183,7 +169,7 @@
 #ifndef FTC_INLINE
 
   FT_LOCAL_DEF( FT_Error )
-  FTC_GCache_Lookup( FTC_GCache   cache,
+  FTC_GCache_Lookup( FTC_GCache   gcache,
                      FT_Offset    hash,
                      FT_UInt      gindex,
                      FTC_GQuery   query,
@@ -204,7 +190,7 @@
       /* out-of-memory condition occurs during glyph node initialization. */
       family->num_nodes++;
 
-      error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, anode );
+      error = FTC_Cache_Lookup( FTC_CACHE( gcache ), hash, query, anode );
 
       if ( --family->num_nodes == 0 )
         FTC_FAMILY_FREE( family, cache );
diff --git a/src/cache/ftcglyph.h b/src/cache/ftcglyph.h
index 728d4db..0181e98 100644
--- a/src/cache/ftcglyph.h
+++ b/src/cache/ftcglyph.h
@@ -58,7 +58,7 @@
    * - FTC_GNode sub-class, e.g. MyNode, with relevant methods:
    *     my_node_new            (must call FTC_GNode_Init)
    *     my_node_free           (must call FTC_GNode_Done)
-   *     my_node_compare        (must call FTC_GNode_Compare)
+   *     my_node_compare        (must call ftc_gnode_compare)
    *     my_node_remove_faceid  (must call ftc_gnode_unselect in case
    *                             of match)
    *
@@ -179,19 +179,6 @@
                   FT_UInt     gindex,  /* glyph index for node */
                   FTC_Family  family );
 
-#ifdef FTC_INLINE
-
-  /* returns TRUE iff the query's glyph index correspond to the node;  */
-  /* this assumes that the `family' and `hash' fields of the query are */
-  /* already correctly set                                             */
-  FT_LOCAL( FT_Bool )
-  FTC_GNode_Compare( FTC_GNode   gnode,
-                     FTC_GQuery  gquery,
-                     FTC_Cache   cache,
-                     FT_Bool*    list_changed );
-
-#endif
-
   /* call this function to clear a node's family -- this is necessary */
   /* to implement the `node_remove_faceid' cache method correctly     */
   FT_LOCAL( void )
diff --git a/src/cache/ftcmanag.c b/src/cache/ftcmanag.c
index 6c84339..94f8469 100644
--- a/src/cache/ftcmanag.c
+++ b/src/cache/ftcmanag.c
@@ -426,7 +426,7 @@
     memory = manager->memory;
 
     /* now discard all caches */
-    for (idx = manager->num_caches; idx-- > 0; )
+    for ( idx = manager->num_caches; idx-- > 0; )
     {
       FTC_Cache  cache = manager->caches[idx];
 
@@ -537,7 +537,7 @@
   FT_LOCAL_DEF( void )
   FTC_Manager_Compress( FTC_Manager  manager )
   {
-    FTC_Node   node, first;
+    FTC_Node   node, prev, first;
 
 
     if ( !manager )
@@ -557,20 +557,16 @@
       return;
 
     /* go to last node -- it's a circular list */
-    node = FTC_NODE_PREV( first );
+    prev = FTC_NODE_PREV( first );
     do
     {
-      FTC_Node  prev;
-
-
-      prev = ( node == first ) ? NULL : FTC_NODE_PREV( node );
+      node = prev;
+      prev = FTC_NODE_PREV( node );
 
       if ( node->ref_count <= 0 )
         ftc_node_destroy( node, manager );
 
-      node = prev;
-
-    } while ( node && manager->cur_weight > manager->max_weight );
+    } while ( node != first && manager->cur_weight > manager->max_weight );
   }
 
 
@@ -633,20 +629,20 @@
                       FT_UInt      count )
   {
     FTC_Node  first = manager->nodes_list;
-    FTC_Node  node;
-    FT_UInt   result;
+    FTC_Node  prev, node;
+    FT_UInt   result = 0;
 
 
     /* try to remove `count' nodes from the list */
-    if ( !first )  /* empty list! */
-      return 0;
+    if ( !first || !count )
+      return result;
 
-    /* go to last node - it's a circular list */
-    node = FTC_NODE_PREV(first);
-    for ( result = 0; result < count; )
+    /* go to last node -- it's a circular list */
+    prev = FTC_NODE_PREV( first );
+    do
     {
-      FTC_Node  prev = FTC_NODE_PREV( node );
-
+      node = prev;
+      prev = FTC_NODE_PREV( node );
 
       /* don't touch locked nodes */
       if ( node->ref_count <= 0 )
@@ -654,13 +650,9 @@
         ftc_node_destroy( node, manager );
         result++;
       }
+    } while ( node != first && result < count );
 
-      if ( node == first )
-        break;
-
-      node = prev;
-    }
-    return  result;
+    return result;
   }
 
 
diff --git a/src/cache/ftcmru.c b/src/cache/ftcmru.c
index 6722703..ad10a06 100644
--- a/src/cache/ftcmru.c
+++ b/src/cache/ftcmru.c
@@ -329,29 +329,23 @@
                                FTC_MruNode_CompareFunc  selection,
                                FT_Pointer               key )
   {
-    FTC_MruNode  first, node, next;
+    FTC_MruNode  first = list->nodes;
+    FTC_MruNode  prev, node;
 
 
-    first = list->nodes;
-    while ( first && ( !selection || selection( first, key ) ) )
+    if ( !first || !selection )
+      return;
+
+    prev = first->prev;
+    do
     {
-      FTC_MruList_Remove( list, first );
-      first = list->nodes;
-    }
+      node = prev;
+      prev = node->prev;
 
-    if ( first )
-    {
-      node = first->next;
-      while ( node != first )
-      {
-        next = node->next;
+      if ( selection( node, key ) )
+        FTC_MruList_Remove( list, node );
 
-        if ( selection( node, key ) )
-          FTC_MruList_Remove( list, node );
-
-        node = next;
-      }
-    }
+    } while ( node != first );
   }
 
 
diff --git a/src/cache/ftcsbits.c b/src/cache/ftcsbits.c
index ee9dab2..9929a0b 100644
--- a/src/cache/ftcsbits.c
+++ b/src/cache/ftcsbits.c
@@ -342,7 +342,7 @@
     FT_Bool     result;
 
 
-    if (list_changed)
+    if ( list_changed )
       *list_changed = FALSE;
     result = FT_BOOL( gnode->family == gquery->family       &&
                       gindex - gnode->gindex < snode->count );
@@ -411,19 +411,4 @@
     return result;
   }
 
-
-#ifdef FTC_INLINE
-
-  FT_LOCAL_DEF( FT_Bool )
-  FTC_SNode_Compare( FTC_SNode   snode,
-                     FTC_GQuery  gquery,
-                     FTC_Cache   cache,
-                     FT_Bool*    list_changed )
-  {
-    return ftc_snode_compare( FTC_NODE( snode ), gquery,
-                              cache, list_changed );
-  }
-
-#endif
-
 /* END */
diff --git a/src/cache/ftcsbits.h b/src/cache/ftcsbits.h
index 3473923..e833cb5 100644
--- a/src/cache/ftcsbits.h
+++ b/src/cache/ftcsbits.h
@@ -81,17 +81,6 @@
   FTC_SNode_Weight( FTC_SNode  inode );
 #endif
 
-
-#ifdef FTC_INLINE
-
-  FT_LOCAL( FT_Bool )
-  FTC_SNode_Compare( FTC_SNode   snode,
-                     FTC_GQuery  gquery,
-                     FTC_Cache   cache,
-                     FT_Bool*    list_changed);
-
-#endif
-
   /* */
 
 FT_END_HEADER
diff --git a/src/cff/cffcmap.c b/src/cff/cffcmap.c
index 6ed3143..10d287b 100644
--- a/src/cff/cffcmap.c
+++ b/src/cff/cffcmap.c
@@ -32,9 +32,10 @@
   /*************************************************************************/
 
   FT_CALLBACK_DEF( FT_Error )
-  cff_cmap_encoding_init( CFF_CMapStd  cmap,
-                          FT_Pointer   pointer )
+  cff_cmap_encoding_init( FT_CMap     cmap,
+                          FT_Pointer  pointer )
   {
+    CFF_CMapStd   cffcmap  = (CFF_CMapStd)cmap;
     TT_Face       face     = (TT_Face)FT_CMAP_FACE( cmap );
     CFF_Font      cff      = (CFF_Font)face->extra.data;
     CFF_Encoding  encoding = &cff->encoding;
@@ -42,63 +43,56 @@
     FT_UNUSED( pointer );
 
 
-    cmap->gids  = encoding->codes;
+    cffcmap->gids = encoding->codes;
 
     return 0;
   }
 
 
   FT_CALLBACK_DEF( void )
-  cff_cmap_encoding_done( CFF_CMapStd  cmap )
+  cff_cmap_encoding_done( FT_CMap  cmap )
   {
-    cmap->gids  = NULL;
+    CFF_CMapStd  cffcmap = (CFF_CMapStd)cmap;
+
+
+    cffcmap->gids = NULL;
   }
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  cff_cmap_encoding_char_index( CFF_CMapStd  cmap,
-                                FT_UInt32    char_code )
+  cff_cmap_encoding_char_index( FT_CMap    cmap,
+                                FT_UInt32  char_code )
   {
-    FT_UInt  result = 0;
+    CFF_CMapStd  cffcmap = (CFF_CMapStd)cmap;
+    FT_UInt      result  = 0;
 
 
     if ( char_code < 256 )
-      result = cmap->gids[char_code];
+      result = cffcmap->gids[char_code];
 
     return result;
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  cff_cmap_encoding_char_next( CFF_CMapStd   cmap,
-                               FT_UInt32    *pchar_code )
+  FT_CALLBACK_DEF( FT_UInt )
+  cff_cmap_encoding_char_next( FT_CMap     cmap,
+                               FT_UInt32  *pchar_code )
   {
-    FT_UInt    result    = 0;
-    FT_UInt32  char_code = *pchar_code;
+    CFF_CMapStd  cffcmap   = (CFF_CMapStd)cmap;
+    FT_UInt      result    = 0;
+    FT_UInt32    char_code = *pchar_code;
 
 
-    *pchar_code = 0;
-
-    if ( char_code < 255 )
+    while ( char_code < 255 )
     {
-      FT_UInt  code = (FT_UInt)( char_code + 1 );
-
-
-      for (;;)
+      result = cffcmap->gids[++char_code];
+      if ( result )
       {
-        if ( code >= 256 )
-          break;
-
-        result = cmap->gids[code];
-        if ( result != 0 )
-        {
-          *pchar_code = code;
-          break;
-        }
-
-        code++;
+        *pchar_code = char_code;
+        break;
       }
     }
+
     return result;
   }
 
@@ -130,9 +124,10 @@
   /*************************************************************************/
 
   FT_CALLBACK_DEF( const char* )
-  cff_sid_to_glyph_name( TT_Face  face,
+  cff_sid_to_glyph_name( void*    face_,  /* TT_Face */
                          FT_UInt  idx )
   {
+    TT_Face      face    = (TT_Face)face_;
     CFF_Font     cff     = (CFF_Font)face->extra.data;
     CFF_Charset  charset = &cff->charset;
     FT_UInt      sid     = charset->sids[idx];
@@ -143,14 +138,15 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  cff_cmap_unicode_init( PS_Unicodes  unicodes,
+  cff_cmap_unicode_init( FT_CMap      cmap,     /* PS_Unicodes */
                          FT_Pointer   pointer )
   {
-    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
-    FT_Memory           memory  = FT_FACE_MEMORY( face );
-    CFF_Font            cff     = (CFF_Font)face->extra.data;
-    CFF_Charset         charset = &cff->charset;
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)cff->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    TT_Face             face     = (TT_Face)FT_CMAP_FACE( cmap );
+    FT_Memory           memory   = FT_FACE_MEMORY( face );
+    CFF_Font            cff      = (CFF_Font)face->extra.data;
+    CFF_Charset         charset  = &cff->charset;
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)cff->psnames;
 
     FT_UNUSED( pointer );
 
@@ -166,17 +162,18 @@
     return psnames->unicodes_init( memory,
                                    unicodes,
                                    cff->num_glyphs,
-                                   (PS_GetGlyphNameFunc)&cff_sid_to_glyph_name,
+                                   &cff_sid_to_glyph_name,
                                    (PS_FreeGlyphNameFunc)NULL,
                                    (FT_Pointer)face );
   }
 
 
   FT_CALLBACK_DEF( void )
-  cff_cmap_unicode_done( PS_Unicodes  unicodes )
+  cff_cmap_unicode_done( FT_CMap  cmap )    /* PS_Unicodes */
   {
-    FT_Face    face   = FT_CMAP_FACE( unicodes );
-    FT_Memory  memory = FT_FACE_MEMORY( face );
+    PS_Unicodes  unicodes = (PS_Unicodes)cmap;
+    FT_Face      face     = FT_CMAP_FACE( cmap );
+    FT_Memory    memory   = FT_FACE_MEMORY( face );
 
 
     FT_FREE( unicodes->maps );
@@ -185,25 +182,27 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  cff_cmap_unicode_char_index( PS_Unicodes  unicodes,
-                               FT_UInt32    char_code )
+  cff_cmap_unicode_char_index( FT_CMap    cmap,       /* PS_Unicodes */
+                               FT_UInt32  char_code )
   {
-    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
-    CFF_Font            cff     = (CFF_Font)face->extra.data;
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)cff->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    TT_Face             face     = (TT_Face)FT_CMAP_FACE( cmap );
+    CFF_Font            cff      = (CFF_Font)face->extra.data;
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)cff->psnames;
 
 
     return psnames->unicodes_char_index( unicodes, char_code );
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  cff_cmap_unicode_char_next( PS_Unicodes  unicodes,
-                              FT_UInt32   *pchar_code )
+  FT_CALLBACK_DEF( FT_UInt )
+  cff_cmap_unicode_char_next( FT_CMap     cmap,        /* PS_Unicodes */
+                              FT_UInt32  *pchar_code )
   {
-    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
-    CFF_Font            cff     = (CFF_Font)face->extra.data;
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)cff->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    TT_Face             face     = (TT_Face)FT_CMAP_FACE( cmap );
+    CFF_Font            cff      = (CFF_Font)face->extra.data;
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)cff->psnames;
 
 
     return psnames->unicodes_char_next( unicodes, pchar_code );
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index 688c4c0..9898d62 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -108,20 +108,20 @@
    *   They can be implemented by format-specific interfaces.
    */
   FT_CALLBACK_DEF( FT_Error )
-  cff_get_kerning( FT_Face     ttface,          /* TT_Face */
+  cff_get_kerning( FT_Face     face,          /* CFF_Face */
                    FT_UInt     left_glyph,
                    FT_UInt     right_glyph,
                    FT_Vector*  kerning )
   {
-    TT_Face       face = (TT_Face)ttface;
-    SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
+    CFF_Face      cffface = (CFF_Face)face;
+    SFNT_Service  sfnt    = (SFNT_Service)cffface->sfnt;
 
 
     kerning->x = 0;
     kerning->y = 0;
 
     if ( sfnt )
-      kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
+      kerning->x = sfnt->get_kerning( cffface, left_glyph, right_glyph );
 
     return FT_Err_Ok;
   }
@@ -158,23 +158,23 @@
    *   FreeType error code.  0 means success.
    */
   FT_CALLBACK_DEF( FT_Error )
-  cff_glyph_load( FT_GlyphSlot  cffslot,      /* CFF_GlyphSlot */
-                  FT_Size       cffsize,      /* CFF_Size      */
+  cff_glyph_load( FT_GlyphSlot  slot,        /* CFF_GlyphSlot */
+                  FT_Size       size,        /* CFF_Size      */
                   FT_UInt       glyph_index,
                   FT_Int32      load_flags )
   {
     FT_Error       error;
-    CFF_GlyphSlot  slot = (CFF_GlyphSlot)cffslot;
-    CFF_Size       size = (CFF_Size)cffsize;
+    CFF_GlyphSlot  cffslot = (CFF_GlyphSlot)slot;
+    CFF_Size       cffsize = (CFF_Size)size;
 
 
-    if ( !slot )
+    if ( !cffslot )
       return FT_THROW( Invalid_Slot_Handle );
 
     FT_TRACE1(( "cff_glyph_load: glyph index %d\n", glyph_index ));
 
     /* check whether we want a scaled outline or bitmap */
-    if ( !size )
+    if ( !cffsize )
       load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
 
     /* reset the size object if necessary */
@@ -184,12 +184,12 @@
     if ( size )
     {
       /* these two objects must have the same parent */
-      if ( cffsize->face != cffslot->face )
+      if ( size->face != slot->face )
         return FT_THROW( Invalid_Face_Handle );
     }
 
     /* now load the glyph outline if necessary */
-    error = cff_slot_load( slot, size, glyph_index, load_flags );
+    error = cff_slot_load( cffslot, cffsize, glyph_index, load_flags );
 
     /* force drop-out mode to 2 - irrelevant now */
     /* slot->outline.dropout_mode = 2; */
@@ -216,7 +216,7 @@
       /* it is no longer necessary that those values are identical to   */
       /* the values in the `CFF' table                                  */
 
-      TT_Face   ttface = (TT_Face)face;
+      CFF_Face  cffface = (CFF_Face)face;
       FT_Short  dummy;
 
 
@@ -225,7 +225,7 @@
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
         /* no fast retrieval for blended MM fonts without VVAR table */
         if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
-             !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE )  )
+             !( cffface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
           return FT_THROW( Unimplemented_Feature );
 #endif
 
@@ -233,7 +233,7 @@
         /* otherwise we extract the info from the CFF glyphstrings  */
         /* (instead of synthesizing a global value using the `OS/2' */
         /* table)                                                   */
-        if ( !ttface->vertical_info )
+        if ( !cffface->vertical_info )
           goto Missing_Table;
 
         for ( nn = 0; nn < count; nn++ )
@@ -241,11 +241,11 @@
           FT_UShort  ah;
 
 
-          ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface,
-                                                       1,
-                                                       start + nn,
-                                                       &dummy,
-                                                       &ah );
+          ( (SFNT_Service)cffface->sfnt )->get_metrics( cffface,
+                                                        1,
+                                                        start + nn,
+                                                        &dummy,
+                                                        &ah );
 
           FT_TRACE5(( "  idx %d: advance height %d font unit%s\n",
                       start + nn,
@@ -259,12 +259,12 @@
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
         /* no fast retrieval for blended MM fonts without HVAR table */
         if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
-             !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE )  )
+             !( cffface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
           return FT_THROW( Unimplemented_Feature );
 #endif
 
         /* check whether we have data from the `hmtx' table at all */
-        if ( !ttface->horizontal.number_Of_HMetrics )
+        if ( !cffface->horizontal.number_Of_HMetrics )
           goto Missing_Table;
 
         for ( nn = 0; nn < count; nn++ )
@@ -272,11 +272,11 @@
           FT_UShort  aw;
 
 
-          ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface,
-                                                       0,
-                                                       start + nn,
-                                                       &dummy,
-                                                       &aw );
+          ( (SFNT_Service)cffface->sfnt )->get_metrics( cffface,
+                                                        0,
+                                                        start + nn,
+                                                        &dummy,
+                                                        &aw );
 
           FT_TRACE5(( "  idx %d: advance width %d font unit%s\n",
                       start + nn,
@@ -312,13 +312,14 @@
    *
    */
 
-  static FT_Error
-  cff_get_glyph_name( CFF_Face    face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_glyph_name( FT_Face     face,        /* CFF_Face */
                       FT_UInt     glyph_index,
                       FT_Pointer  buffer,
                       FT_UInt     buffer_max )
   {
-    CFF_Font    font   = (CFF_Font)face->extra.data;
+    CFF_Face    cffface = (CFF_Face)face;
+    CFF_Font    font    = (CFF_Font)cffface->extra.data;
     FT_String*  gname;
     FT_UShort   sid;
     FT_Error    error;
@@ -338,10 +339,7 @@
 
 
       if ( service && service->get_name )
-        return service->get_name( FT_FACE( face ),
-                                  glyph_index,
-                                  buffer,
-                                  buffer_max );
+        return service->get_name( face, glyph_index, buffer, buffer_max );
       else
       {
         FT_ERROR(( "cff_get_glyph_name:"
@@ -366,7 +364,7 @@
     /* first, locate the sid in the charset table */
     sid = font->charset.sids[glyph_index];
 
-    /* now, lookup the name itself */
+    /* now, look up the name itself */
     gname = cff_index_get_sid_string( font, sid );
 
     if ( gname )
@@ -379,21 +377,19 @@
   }
 
 
-  static FT_UInt
-  cff_get_name_index( CFF_Face          face,
+  FT_CALLBACK_DEF( FT_UInt )
+  cff_get_name_index( FT_Face           face,        /* CFF_Face */
                       const FT_String*  glyph_name )
   {
-    CFF_Font            cff;
-    CFF_Charset         charset;
+    CFF_Face            cffface = (CFF_Face)face;
+    CFF_Font            cff     = (CFF_Font)cffface->extra.data;
+    CFF_Charset         charset = &cff->charset;
     FT_Service_PsCMaps  psnames;
     FT_String*          name;
     FT_UShort           sid;
     FT_UInt             i;
 
 
-    cff     = (CFF_FontRec *)face->extra.data;
-    charset = &cff->charset;
-
     /* CFF2 table does not have glyph names; */
     /* we need to use `post' table method    */
     if ( cff->version_major == 2 )
@@ -408,7 +404,7 @@
 
 
       if ( service && service->name_index )
-        return service->name_index( FT_FACE( face ), glyph_name );
+        return service->name_index( face, glyph_name );
       else
       {
         FT_ERROR(( "cff_get_name_index:"
@@ -446,8 +442,8 @@
   FT_DEFINE_SERVICE_GLYPHDICTREC(
     cff_service_glyph_dict,
 
-    (FT_GlyphDict_GetNameFunc)  cff_get_glyph_name,      /* get_name   */
-    (FT_GlyphDict_NameIndexFunc)cff_get_name_index       /* name_index */
+    cff_get_glyph_name,  /* FT_GlyphDict_GetNameFunc   get_name   */
+    cff_get_name_index   /* FT_GlyphDict_NameIndexFunc name_index */
   )
 
 
@@ -456,25 +452,32 @@
    *
    */
 
-  static FT_Int
+  FT_CALLBACK_DEF( FT_Int )
   cff_ps_has_glyph_names( FT_Face  face )
   {
     return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0;
   }
 
 
-  static FT_Error
-  cff_ps_get_font_info( CFF_Face         face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_ps_get_font_info( FT_Face          face,        /* CFF_Face */
                         PS_FontInfoRec*  afont_info )
   {
-    CFF_Font  cff   = (CFF_Font)face->extra.data;
-    FT_Error  error = FT_Err_Ok;
+    CFF_Face  cffface = (CFF_Face)face;
+    CFF_Font  cff     = (CFF_Font)cffface->extra.data;
+    FT_Error  error   = FT_Err_Ok;
 
 
+    if ( cffface->is_cff2 )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Fail;
+    }
+
     if ( cff && !cff->font_info )
     {
       CFF_FontRecDict  dict      = &cff->top_font.font_dict;
-      FT_Memory        memory    = face->root.memory;
+      FT_Memory        memory    = FT_FACE_MEMORY( face );
       PS_FontInfoRec*  font_info = NULL;
 
 
@@ -507,18 +510,19 @@
   }
 
 
-  static FT_Error
-  cff_ps_get_font_extra( CFF_Face          face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_ps_get_font_extra( FT_Face           face,         /* CFF_Face */
                          PS_FontExtraRec*  afont_extra )
   {
-    CFF_Font  cff   = (CFF_Font)face->extra.data;
-    FT_Error  error = FT_Err_Ok;
+    CFF_Face  cffface = (CFF_Face)face;
+    CFF_Font  cff     = (CFF_Font)cffface->extra.data;
+    FT_Error  error   = FT_Err_Ok;
 
 
     if ( cff && !cff->font_extra )
     {
       CFF_FontRecDict   dict       = &cff->top_font.font_dict;
-      FT_Memory         memory     = face->root.memory;
+      FT_Memory         memory     = FT_FACE_MEMORY( face );
       PS_FontExtraRec*  font_extra = NULL;
       FT_String*        embedded_postscript;
 
@@ -588,13 +592,13 @@
   FT_DEFINE_SERVICE_PSINFOREC(
     cff_service_ps_info,
 
-    (PS_GetFontInfoFunc)   cff_ps_get_font_info,    /* ps_get_font_info    */
-    (PS_GetFontExtraFunc)  cff_ps_get_font_extra,   /* ps_get_font_extra   */
-    (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,  /* ps_has_glyph_names  */
+    cff_ps_get_font_info,    /* PS_GetFontInfoFunc    ps_get_font_info    */
+    cff_ps_get_font_extra,   /* PS_GetFontExtraFunc   ps_get_font_extra   */
+    cff_ps_has_glyph_names,  /* PS_HasGlyphNamesFunc  ps_has_glyph_names  */
     /* unsupported with CFF fonts */
-    (PS_GetFontPrivateFunc)NULL,                    /* ps_get_font_private */
+    NULL,                    /* PS_GetFontPrivateFunc ps_get_font_private */
     /* not implemented            */
-    (PS_GetFontValueFunc)  NULL                     /* ps_get_font_value   */
+    NULL                     /* PS_GetFontValueFunc   ps_get_font_value   */
   )
 
 
@@ -603,17 +607,18 @@
    *
    */
 
-  static const char*
-  cff_get_ps_name( CFF_Face  face )
+  FT_CALLBACK_DEF( const char* )
+  cff_get_ps_name( FT_Face  face )    /* CFF_Face */
   {
-    CFF_Font      cff  = (CFF_Font)face->extra.data;
-    SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
+    CFF_Face      cffface = (CFF_Face)face;
+    CFF_Font      cff     = (CFF_Font)cffface->extra.data;
+    SFNT_Service  sfnt    = (SFNT_Service)cffface->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 ( FT_IS_SFNT( FT_FACE( face ) ) && sfnt )
+    if ( FT_IS_SFNT( face ) && sfnt )
     {
       FT_Library             library     = FT_FACE_LIBRARY( face );
       FT_Module              sfnt_module = FT_Get_Module( library, "sfnt" );
@@ -625,17 +630,17 @@
 
 
       if ( service && service->get_ps_font_name )
-        return service->get_ps_font_name( FT_FACE( face ) );
+        return service->get_ps_font_name( face );
     }
 
-    return (const char*)cff->font_name;
+    return cff ? (const char*)cff->font_name : NULL;
   }
 
 
   FT_DEFINE_SERVICE_PSFONTNAMEREC(
     cff_service_ps_name,
 
-    (FT_PsName_GetFunc)cff_get_ps_name      /* get_ps_font_name */
+    cff_get_ps_name  /* FT_PsName_GetFunc get_ps_font_name */
   )
 
 
@@ -649,7 +654,7 @@
    * Otherwise call the service function in the sfnt module.
    *
    */
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   cff_get_cmap_info( FT_CharMap    charmap,
                      TT_CMapInfo  *cmap_info )
   {
@@ -683,7 +688,7 @@
   FT_DEFINE_SERVICE_TTCMAPSREC(
     cff_service_get_cmap_info,
 
-    (TT_CMap_Info_GetFunc)cff_get_cmap_info    /* get_cmap_info */
+    cff_get_cmap_info  /* TT_CMap_Info_GetFunc get_cmap_info */
   )
 
 
@@ -691,14 +696,15 @@
    * CID INFO SERVICE
    *
    */
-  static FT_Error
-  cff_get_ros( CFF_Face      face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_ros( FT_Face       face,        /* FT_Face */
                const char*  *registry,
                const char*  *ordering,
                FT_Int       *supplement )
   {
-    FT_Error  error = FT_Err_Ok;
-    CFF_Font  cff   = (CFF_Font)face->extra.data;
+    FT_Error  error   = FT_Err_Ok;
+    CFF_Face  cffface = (CFF_Face)face;
+    CFF_Font  cff     = (CFF_Font)cffface->extra.data;
 
 
     if ( cff )
@@ -748,12 +754,13 @@
   }
 
 
-  static FT_Error
-  cff_get_is_cid( CFF_Face  face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_is_cid( FT_Face   face,    /* CFF_Face */
                   FT_Bool  *is_cid )
   {
-    FT_Error  error = FT_Err_Ok;
-    CFF_Font  cff   = (CFF_Font)face->extra.data;
+    FT_Error  error   = FT_Err_Ok;
+    CFF_Face  cffface = (CFF_Face)face;
+    CFF_Font  cff     = (CFF_Font)cffface->extra.data;
 
 
     *is_cid = 0;
@@ -771,17 +778,16 @@
   }
 
 
-  static FT_Error
-  cff_get_cid_from_glyph_index( CFF_Face  face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_cid_from_glyph_index( FT_Face   face,        /* CFF_Face */
                                 FT_UInt   glyph_index,
                                 FT_UInt  *cid )
   {
-    FT_Error  error = FT_Err_Ok;
-    CFF_Font  cff;
+    FT_Error  error   = FT_Err_Ok;
+    CFF_Face  cffface = (CFF_Face)face;
+    CFF_Font  cff     = (CFF_Font)cffface->extra.data;
 
 
-    cff = (CFF_Font)face->extra.data;
-
     if ( cff )
     {
       FT_UInt          c;
@@ -814,12 +820,12 @@
   FT_DEFINE_SERVICE_CIDREC(
     cff_service_cid_info,
 
-    (FT_CID_GetRegistryOrderingSupplementFunc)
-      cff_get_ros,                             /* get_ros                  */
-    (FT_CID_GetIsInternallyCIDKeyedFunc)
-      cff_get_is_cid,                          /* get_is_cid               */
-    (FT_CID_GetCIDFromGlyphIndexFunc)
-      cff_get_cid_from_glyph_index             /* get_cid_from_glyph_index */
+    cff_get_ros,
+      /* FT_CID_GetRegistryOrderingSupplementFunc get_ros                  */
+    cff_get_is_cid,
+      /* FT_CID_GetIsInternallyCIDKeyedFunc       get_is_cid               */
+    cff_get_cid_from_glyph_index
+      /* FT_CID_GetCIDFromGlyphIndexFunc          get_cid_from_glyph_index */
   )
 
 
@@ -831,9 +837,9 @@
   FT_DEFINE_SERVICE_PROPERTIESREC(
     cff_service_properties,
 
-    (FT_Properties_SetFunc)ps_property_set,      /* set_property */
-    (FT_Properties_GetFunc)ps_property_get )     /* get_property */
-
+    ps_property_set,  /* FT_Properties_SetFunc set_property */
+    ps_property_get   /* FT_Properties_GetFunc get_property */
+  )
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
@@ -842,160 +848,195 @@
    *
    */
 
-  static FT_Error
-  cff_set_mm_blend( CFF_Face   face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_set_mm_blend( FT_Face    face,        /* CFF_Face */
                     FT_UInt    num_coords,
                     FT_Fixed*  coords )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->set_mm_blend( FT_FACE( face ), num_coords, coords );
+    return mm->set_mm_blend( face, num_coords, coords );
   }
 
 
-  static FT_Error
-  cff_get_mm_blend( CFF_Face   face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_mm_blend( FT_Face    face,       /* CFF_Face */
                     FT_UInt    num_coords,
                     FT_Fixed*  coords )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->get_mm_blend( FT_FACE( face ), num_coords, coords );
+    return mm->get_mm_blend( face, num_coords, coords );
   }
 
 
-  static FT_Error
-  cff_set_mm_weightvector( CFF_Face   face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_set_mm_weightvector( FT_Face    face,          /* CFF_Face */
                            FT_UInt    len,
                            FT_Fixed*  weightvector )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->set_mm_weightvector( FT_FACE( face ), len, weightvector );
+    return mm->set_mm_weightvector( face, len, weightvector );
   }
 
 
-  static FT_Error
-  cff_get_mm_weightvector( CFF_Face   face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_mm_weightvector( FT_Face    face,          /* CFF_Face */
                            FT_UInt*   len,
                            FT_Fixed*  weightvector )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->get_mm_weightvector( FT_FACE( face ), len, weightvector );
+    return mm->get_mm_weightvector( face, len, weightvector );
   }
 
 
-  static FT_Error
-  cff_get_mm_var( CFF_Face     face,
+  FT_CALLBACK_DEF( void )
+  cff_construct_ps_name( FT_Face  face )  /* CFF_Face */
+  {
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
+
+
+    mm->construct_ps_name( face );
+  }
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_mm_var( FT_Face      face,    /* CFF_Face */
                   FT_MM_Var*  *master )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->get_mm_var( FT_FACE( face ), master );
+    return mm->get_mm_var( face, master );
   }
 
 
-  static FT_Error
-  cff_set_var_design( CFF_Face   face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_set_var_design( FT_Face    face,       /* CFF_Face */
                       FT_UInt    num_coords,
                       FT_Fixed*  coords )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->set_var_design( FT_FACE( face ), num_coords, coords );
+    return mm->set_var_design( face, num_coords, coords );
   }
 
 
-  static FT_Error
-  cff_get_var_design( CFF_Face   face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_var_design( FT_Face    face,       /* CFF_Face */
                       FT_UInt    num_coords,
                       FT_Fixed*  coords )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->get_var_design( FT_FACE( face ), num_coords, coords );
+    return mm->get_var_design( face, num_coords, coords );
   }
 
 
-  static FT_Error
-  cff_set_instance( CFF_Face  face,
-                    FT_UInt   instance_index )
+  FT_CALLBACK_DEF( FT_Error )
+  cff_set_named_instance( FT_Face   face,            /* CFF_Face */
+                          FT_UInt   instance_index )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->set_instance( FT_FACE( face ), instance_index );
+    return mm->set_named_instance( face, instance_index );
   }
 
 
-  static FT_Error
-  cff_load_item_variation_store( CFF_Face         face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_default_named_instance( FT_Face   face,            /* CFF_Face */
+                                  FT_UInt  *instance_index )
+  {
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
+
+
+    return mm->get_default_named_instance( face, instance_index );
+  }
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  cff_load_item_variation_store( FT_Face          face,       /* CFF_Face */
                                  FT_ULong         offset,
                                  GX_ItemVarStore  itemStore )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->load_item_var_store( FT_FACE(face), offset, itemStore );
+    return mm->load_item_var_store( face, offset, itemStore );
   }
 
 
-  static FT_Error
-  cff_load_delta_set_index_mapping( CFF_Face           face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_load_delta_set_index_mapping( FT_Face            face,   /* CFF_Face */
                                     FT_ULong           offset,
                                     GX_DeltaSetIdxMap  map,
                                     GX_ItemVarStore    itemStore,
                                     FT_ULong           table_len )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->load_delta_set_idx_map( FT_FACE( face ), offset, map,
+    return mm->load_delta_set_idx_map( face, offset, map,
                                        itemStore, table_len );
   }
 
 
-  static FT_Int
-  cff_get_item_delta( CFF_Face         face,
+  FT_CALLBACK_DEF( FT_Int )
+  cff_get_item_delta( FT_Face          face,        /* CFF_Face */
                       GX_ItemVarStore  itemStore,
                       FT_UInt          outerIndex,
                       FT_UInt          innerIndex )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->get_item_delta( FT_FACE( face ), itemStore,
-                               outerIndex, innerIndex );
+    return mm->get_item_delta( face, itemStore, outerIndex, innerIndex );
   }
 
 
-  static void
-  cff_done_item_variation_store( CFF_Face          face,
+  FT_CALLBACK_DEF( void )
+  cff_done_item_variation_store( FT_Face          face,       /* CFF_Face */
                                  GX_ItemVarStore  itemStore )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    mm->done_item_var_store( FT_FACE( face ), itemStore );
+    mm->done_item_var_store( face, itemStore );
   }
 
 
-  static void
-  cff_done_delta_set_index_map( CFF_Face           face,
+  FT_CALLBACK_DEF( void )
+  cff_done_delta_set_index_map( FT_Face            face,       /* CFF_Face */
                                 GX_DeltaSetIdxMap  deltaSetIdxMap )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    mm->done_delta_set_idx_map( FT_FACE ( face ), deltaSetIdxMap );
+    mm->done_delta_set_idx_map( face, deltaSetIdxMap );
   }
 
 
@@ -1003,36 +1044,35 @@
   FT_DEFINE_SERVICE_MULTIMASTERSREC(
     cff_service_multi_masters,
 
-    (FT_Get_MM_Func)        NULL,               /* get_mm                    */
-    (FT_Set_MM_Design_Func) NULL,               /* set_mm_design             */
-    (FT_Set_MM_Blend_Func)  cff_set_mm_blend,   /* set_mm_blend              */
-    (FT_Get_MM_Blend_Func)  cff_get_mm_blend,   /* get_mm_blend              */
-    (FT_Get_MM_Var_Func)    cff_get_mm_var,     /* get_mm_var                */
-    (FT_Set_Var_Design_Func)cff_set_var_design, /* set_var_design            */
-    (FT_Get_Var_Design_Func)cff_get_var_design, /* get_var_design            */
-    (FT_Set_Instance_Func)  cff_set_instance,   /* set_instance              */
-    (FT_Set_MM_WeightVector_Func)
-                            cff_set_mm_weightvector,
-                                                /* set_mm_weightvector       */
-    (FT_Get_MM_WeightVector_Func)
-                            cff_get_mm_weightvector,
-                                                /* get_mm_weightvector       */
-    (FT_Var_Load_Delta_Set_Idx_Map_Func)
-                            cff_load_delta_set_index_mapping,
-                                                /* load_delta_set_idx_map    */
-    (FT_Var_Load_Item_Var_Store_Func)
-                            cff_load_item_variation_store,
-                                                /* load_item_variation_store */
-    (FT_Var_Get_Item_Delta_Func)
-                            cff_get_item_delta, /* get_item_delta            */
-    (FT_Var_Done_Item_Var_Store_Func)
-                            cff_done_item_variation_store,
-                                                /* done_item_variation_store */
-    (FT_Var_Done_Delta_Set_Idx_Map_Func)
-                            cff_done_delta_set_index_map,
-                                                /* done_delta_set_index_map  */
-    (FT_Get_Var_Blend_Func) cff_get_var_blend,  /* get_var_blend             */
-    (FT_Done_Blend_Func)    cff_done_blend      /* done_blend                */
+    NULL,                /* FT_Get_MM_Func         get_mm                     */
+    NULL,                /* FT_Set_MM_Design_Func  set_mm_design              */
+    cff_set_mm_blend,    /* FT_Set_MM_Blend_Func   set_mm_blend               */
+    cff_get_mm_blend,    /* FT_Get_MM_Blend_Func   get_mm_blend               */
+    cff_get_mm_var,      /* FT_Get_MM_Var_Func     get_mm_var                 */
+    cff_set_var_design,  /* FT_Set_Var_Design_Func set_var_design             */
+    cff_get_var_design,  /* FT_Get_Var_Design_Func get_var_design             */
+    cff_set_named_instance,
+             /* FT_Set_Named_Instance_Func         set_named_instance         */
+    cff_get_default_named_instance,
+             /* FT_Get_Default_Named_Instance_Func get_default_named_instance */
+    cff_set_mm_weightvector,
+             /* FT_Set_MM_WeightVector_Func        set_mm_weightvector        */
+    cff_get_mm_weightvector,
+             /* FT_Get_MM_WeightVector_Func        get_mm_weightvector        */
+    cff_construct_ps_name,
+             /* FT_Construct_PS_Name_Func          construct_ps_name          */
+    cff_load_delta_set_index_mapping,
+             /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map     */
+    cff_load_item_variation_store,
+             /* FT_Var_Load_Item_Var_Store_Func    load_item_variation_store  */
+    cff_get_item_delta,
+             /* FT_Var_Get_Item_Delta_Func         get_item_delta             */
+    cff_done_item_variation_store,
+             /* FT_Var_Done_Item_Var_Store_Func    done_item_variation_store  */
+    cff_done_delta_set_index_map,
+             /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map   */
+    cff_get_var_blend,   /* FT_Get_Var_Blend_Func  get_var_blend              */
+    cff_done_blend       /* FT_Done_Blend_Func     done_blend                 */
   )
 
 
@@ -1041,44 +1081,46 @@
    *
    */
 
-  static FT_Error
-  cff_hadvance_adjust( CFF_Face  face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_hadvance_adjust( FT_Face   face,    /* CFF_Face */
                        FT_UInt   gindex,
                        FT_Int   *avalue )
   {
+    CFF_Face  cffface = (CFF_Face)face;
     FT_Service_MetricsVariations
-      var = (FT_Service_MetricsVariations)face->tt_var;
+              var     = (FT_Service_MetricsVariations)cffface->tt_var;
 
 
-    return var->hadvance_adjust( FT_FACE( face ), gindex, avalue );
+    return var->hadvance_adjust( face, gindex, avalue );
   }
 
 
-  static void
-  cff_metrics_adjust( CFF_Face  face )
+  FT_CALLBACK_DEF( void )
+  cff_metrics_adjust( FT_Face  face )    /* CFF_Face */
   {
+    CFF_Face  cffface = (CFF_Face)face;
     FT_Service_MetricsVariations
-      var = (FT_Service_MetricsVariations)face->tt_var;
+              var     = (FT_Service_MetricsVariations)cffface->tt_var;
 
 
-    var->metrics_adjust( FT_FACE( face ) );
+    var->metrics_adjust( face );
   }
 
 
   FT_DEFINE_SERVICE_METRICSVARIATIONSREC(
     cff_service_metrics_variations,
 
-    (FT_HAdvance_Adjust_Func)cff_hadvance_adjust,    /* hadvance_adjust */
-    (FT_LSB_Adjust_Func)     NULL,                   /* lsb_adjust      */
-    (FT_RSB_Adjust_Func)     NULL,                   /* rsb_adjust      */
+    cff_hadvance_adjust,  /* FT_HAdvance_Adjust_Func hadvance_adjust */
+    NULL,                 /* FT_LSB_Adjust_Func      lsb_adjust      */
+    NULL,                 /* FT_RSB_Adjust_Func      rsb_adjust      */
 
-    (FT_VAdvance_Adjust_Func)NULL,                   /* vadvance_adjust */
-    (FT_TSB_Adjust_Func)     NULL,                   /* tsb_adjust      */
-    (FT_BSB_Adjust_Func)     NULL,                   /* bsb_adjust      */
-    (FT_VOrg_Adjust_Func)    NULL,                   /* vorg_adjust     */
+    NULL,                 /* FT_VAdvance_Adjust_Func vadvance_adjust */
+    NULL,                 /* FT_TSB_Adjust_Func      tsb_adjust      */
+    NULL,                 /* FT_BSB_Adjust_Func      bsb_adjust      */
+    NULL,                 /* FT_VOrg_Adjust_Func     vorg_adjust     */
 
-    (FT_Metrics_Adjust_Func) cff_metrics_adjust,     /* metrics_adjust  */
-    (FT_Size_Reset_Func)     NULL                    /* size_reset      */
+    cff_metrics_adjust,   /* FT_Metrics_Adjust_Func  metrics_adjust  */
+    NULL                  /* FT_Size_Reset_Func      size_reset      */
   )
 #endif
 
@@ -1091,11 +1133,11 @@
   FT_DEFINE_SERVICE_CFFLOADREC(
     cff_service_cff_load,
 
-    (FT_Get_Standard_Encoding_Func)cff_get_standard_encoding,
-    (FT_Load_Private_Dict_Func)    cff_load_private_dict,
-    (FT_FD_Select_Get_Func)        cff_fd_select_get,
-    (FT_Blend_Check_Vector_Func)   cff_blend_check_vector,
-    (FT_Blend_Build_Vector_Func)   cff_blend_build_vector
+    cff_get_standard_encoding,  /* FT_Get_Standard_Encoding_Func get_standard_encoding */
+    cff_load_private_dict,      /* FT_Load_Private_Dict_Func     load_private_dict     */
+    cff_fd_select_get,          /* FT_FD_Select_Get_Func         fd_select_get         */
+    cff_blend_check_vector,     /* FT_Blend_Check_Vector_Func    blend_check_vector    */
+    cff_blend_build_vector      /* FT_Blend_Build_Vector_Func    blend_build_vector    */
   )
 
 
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index cfa0aaf..c483d1d 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -356,14 +356,16 @@
 
 #ifdef FT_CONFIG_OPTION_SVG
     /* check for OT-SVG */
-    if ( ( load_flags & FT_LOAD_COLOR ) && face->svg )
+    if ( ( load_flags & FT_LOAD_NO_SVG ) == 0 &&
+         ( load_flags & FT_LOAD_COLOR )       &&
+         face->svg                            )
     {
       /*
        * We load the SVG document and try to grab the advances from the
        * table.  For the bearings we rely on the presetting hook to do that.
        */
 
-      SFNT_Service  sfnt  = (SFNT_Service)face->sfnt;
+      SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
 
 
       if ( size && (size->root.metrics.x_ppem < 1 ||
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index 4b8c6e1..af79082 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -400,7 +400,7 @@
 
   /* Allocate a table containing pointers to an index's elements. */
   /* The `pool' argument makes this function convert the index    */
-  /* entries to C-style strings (this is, null-terminated).       */
+  /* entries to C-style strings (that is, null-terminated).       */
   static FT_Error
   cff_index_get_pointers( CFF_Index   idx,
                           FT_Byte***  table,
@@ -1361,14 +1361,15 @@
     for ( i = 0; i < numBlends; i++ )
     {
       const FT_Int32*  weight = &blend->BV[1];
-      FT_UInt32        sum;
+      FT_Fixed         sum;
 
 
-      /* convert inputs to 16.16 fixed-point */
-      sum = cff_parse_num( parser, &parser->stack[i + base] ) * 0x10000;
+      /* convert inputs to 16.16 fixed point */
+      sum = cff_parse_fixed( parser, &parser->stack[i + base] );
 
       for ( j = 1; j < blend->lenBV; j++ )
-        sum += cff_parse_num( parser, &parser->stack[delta++] ) * *weight++;
+        sum += FT_MulFix( cff_parse_fixed( parser, &parser->stack[delta++] ),
+                          *weight++ );
 
       /* point parser stack to new value on blend_stack */
       parser->stack[i + base] = subFont->blend_top;
@@ -1589,16 +1590,17 @@
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
   FT_LOCAL_DEF( FT_Error )
-  cff_get_var_blend( CFF_Face     face,
+  cff_get_var_blend( FT_Face      face,             /* CFF_Face */
                      FT_UInt     *num_coords,
                      FT_Fixed*   *coords,
                      FT_Fixed*   *normalizedcoords,
                      FT_MM_Var*  *mm_var )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->get_var_blend( FT_FACE( face ),
+    return mm->get_var_blend( face,
                               num_coords,
                               coords,
                               normalizedcoords,
@@ -1607,13 +1609,14 @@
 
 
   FT_LOCAL_DEF( void )
-  cff_done_blend( CFF_Face  face )
+  cff_done_blend( FT_Face  face )    /* CFF_Face */
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    if (mm)
-      mm->done_blend( FT_FACE( face ) );
+    if ( mm )
+      mm->done_blend( face );
   }
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@@ -1650,13 +1653,6 @@
       goto Exit;
     }
 
-    /* Zero out the code to gid/sid mappings. */
-    for ( j = 0; j < 256; j++ )
-    {
-      encoding->sids [j] = 0;
-      encoding->codes[j] = 0;
-    }
-
     /* Note: The encoding table in a CFF font is indexed by glyph index;  */
     /* the first encoded glyph index is 1.  Hence, we read the character  */
     /* code (`glyph_code') at index j and make the assignment:            */
@@ -1671,6 +1667,10 @@
 
     if ( offset > 1 )
     {
+      /* Zero out the code to gid/sid mappings. */
+      FT_ARRAY_ZERO( encoding->sids,  256 );
+      FT_ARRAY_ZERO( encoding->codes, 256 );
+
       encoding->offset = base_offset + offset;
 
       /* we need to parse the table to determine its size */
@@ -2012,7 +2012,7 @@
     /*       Top and Font DICTs are not allowed to have blend operators. */
     error = cff_parser_init( &parser,
                              code,
-                             &subfont->font_dict,
+                             top,
                              font->library,
                              stackSize,
                              0,
diff --git a/src/cff/cffload.h b/src/cff/cffload.h
index 5a41cde..b5286b0 100644
--- a/src/cff/cffload.h
+++ b/src/cff/cffload.h
@@ -105,14 +105,14 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
   FT_LOCAL( FT_Error )
-  cff_get_var_blend( CFF_Face     face,
+  cff_get_var_blend( FT_Face      face,
                      FT_UInt     *num_coords,
                      FT_Fixed*   *coords,
                      FT_Fixed*   *normalizedcoords,
                      FT_MM_Var*  *mm_var );
 
   FT_LOCAL( void )
-  cff_done_blend( CFF_Face  face );
+  cff_done_blend( FT_Face  face );
 #endif
 
 
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index e48336c..6d08620 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -69,8 +69,8 @@
     FT_Module         module;
 
 
-    module = FT_Get_Module( size->root.face->driver->root.library,
-                            "pshinter" );
+    module = FT_Get_Module( font->library, "pshinter" );
+
     return ( module && pshinter && pshinter->get_globals_funcs )
            ? pshinter->get_globals_funcs( module )
            : 0;
@@ -182,8 +182,7 @@
       goto Exit;
 
     cff_make_private_dict( &font->top_font, &priv );
-    error = funcs->create( cffsize->face->memory, &priv,
-                             &internal->topfont );
+    error = funcs->create( memory, &priv, &internal->topfont );
     if ( error )
       goto Exit;
 
@@ -193,8 +192,7 @@
 
 
       cff_make_private_dict( sub, &priv );
-      error = funcs->create( cffsize->face->memory, &priv,
-                               &internal->subfonts[i - 1] );
+      error = funcs->create( memory, &priv, &internal->subfonts[i - 1] );
       if ( error )
         goto Exit;
     }
@@ -381,8 +379,7 @@
       FT_Module  module;
 
 
-      module = FT_Get_Module( slot->face->driver->root.library,
-                              "pshinter" );
+      module = FT_Get_Module( slot->library, "pshinter" );
       if ( module )
       {
         T2_Hints_Funcs  funcs;
@@ -722,24 +719,15 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
       {
-        FT_Service_MultiMasters
-          mm = (FT_Service_MultiMasters)face->mm;
-        FT_Service_MetricsVariations
-          var = (FT_Service_MetricsVariations)face->face_var;
-
         FT_UInt  instance_index = (FT_UInt)face_index >> 16;
 
 
         if ( FT_HAS_MULTIPLE_MASTERS( cffface ) &&
-             mm                                 &&
              instance_index > 0                 )
         {
-          error = mm->set_instance( cffface, instance_index );
+          error = FT_Set_Named_Instance( cffface, instance_index );
           if ( error )
             goto Exit;
-
-          if ( var )
-            var->metrics_adjust( cffface );
         }
       }
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@@ -1162,7 +1150,7 @@
     }
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-    cff_done_blend( face );
+    cff_done_blend( cffface );
     face->blend = NULL;
 #endif
   }
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index e16206f..3b07670 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -63,10 +63,7 @@
 
     /* allocate the stack buffer */
     if ( FT_QNEW_ARRAY( parser->stack, stackSize ) )
-    {
-      FT_FREE( parser->stack );
       goto Exit;
-    }
 
     parser->stackSize = stackSize;
     parser->top       = parser->stack;    /* empty stack */
@@ -76,23 +73,6 @@
   }
 
 
-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-  static void
-  finalize_t2_strings( FT_Memory  memory,
-                       void*      data,
-                       void*      user )
-  {
-    CFF_T2_String  t2 = (CFF_T2_String)data;
-
-
-    FT_UNUSED( user );
-
-    memory->free( memory, t2->start );
-    memory->free( memory, data );
-  }
-#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
-
-
   FT_LOCAL_DEF( void )
   cff_parser_done( CFF_Parser  parser )
   {
@@ -102,63 +82,19 @@
     FT_FREE( parser->stack );
 
 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-    FT_List_Finalize( &parser->t2_strings,
-                      finalize_t2_strings,
-                      memory,
-                      NULL );
+    FT_List_Finalize( &parser->t2_strings, NULL, memory, NULL );
 #endif
   }
 
 
-  /* Assuming `first >= last'. */
-
-  static FT_Error
-  cff_parser_within_limits( CFF_Parser  parser,
-                            FT_Byte*    first,
-                            FT_Byte*    last )
-  {
-#ifndef CFF_CONFIG_OPTION_OLD_ENGINE
-
-    /* Fast path for regular FreeType builds with the "new" engine; */
-    /*   `first >= parser->start' can be assumed.                   */
-
-    FT_UNUSED( first );
-
-    return last < parser->limit ? FT_Err_Ok : FT_THROW( Invalid_Argument );
-
-#else /* CFF_CONFIG_OPTION_OLD_ENGINE */
-
-    FT_ListNode  node;
-
-
-    if ( first >= parser->start &&
-         last  <  parser->limit )
-      return FT_Err_Ok;
-
-    node = parser->t2_strings.head;
-
-    while ( node )
-    {
-      CFF_T2_String  t2 = (CFF_T2_String)node->data;
-
-
-      if ( first >= t2->start &&
-           last  <  t2->limit )
-        return FT_Err_Ok;
-
-      node = node->next;
-    }
-
-    return FT_THROW( Invalid_Argument );
-
-#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
-  }
-
+  /* The parser limit checks in the next two functions are supposed */
+  /* to detect the immediate crossing of the stream boundary.  They */
+  /* shall not be triggered from the distant t2_strings buffers.    */
 
   /* read an integer */
   static FT_Long
-  cff_parse_integer( CFF_Parser  parser,
-                     FT_Byte*    start )
+  cff_parse_integer( FT_Byte*  start,
+                     FT_Byte*  limit )
   {
     FT_Byte*  p   = start;
     FT_Int    v   = *p++;
@@ -167,14 +103,14 @@
 
     if ( v == 28 )
     {
-      if ( cff_parser_within_limits( parser, p, p + 1 ) )
+      if ( p + 2 > limit && limit >= p )
         goto Bad;
 
       val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
     }
     else if ( v == 29 )
     {
-      if ( cff_parser_within_limits( parser, p, p + 3 ) )
+      if ( p + 4 > limit && limit >= p )
         goto Bad;
 
       val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
@@ -188,14 +124,14 @@
     }
     else if ( v < 251 )
     {
-      if ( cff_parser_within_limits( parser, p, p ) )
+      if ( p + 1 > limit && limit >= p )
         goto Bad;
 
       val = ( v - 247 ) * 256 + p[0] + 108;
     }
     else
     {
-      if ( cff_parser_within_limits( parser, p, p ) )
+      if ( p + 1 > limit && limit >= p )
         goto Bad;
 
       val = -( v - 251 ) * 256 - p[0] - 108;
@@ -244,10 +180,10 @@
 
   /* read a real */
   static FT_Fixed
-  cff_parse_real( CFF_Parser  parser,
-                  FT_Byte*    start,
-                  FT_Long     power_ten,
-                  FT_Long*    scaling )
+  cff_parse_real( FT_Byte*  start,
+                  FT_Byte*  limit,
+                  FT_Long   power_ten,
+                  FT_Long*  scaling )
   {
     FT_Byte*  p = start;
     FT_Int    nib;
@@ -282,7 +218,7 @@
         p++;
 
         /* Make sure we don't read past the end. */
-        if ( cff_parser_within_limits( parser, p, p ) )
+        if ( p + 1 > limit && limit >= p )
           goto Bad;
       }
 
@@ -319,7 +255,7 @@
           p++;
 
           /* Make sure we don't read past the end. */
-          if ( cff_parser_within_limits( parser, p, p ) )
+          if ( p + 1 > limit && limit >= p )
             goto Bad;
         }
 
@@ -358,7 +294,7 @@
           p++;
 
           /* Make sure we don't read past the end. */
-          if ( cff_parser_within_limits( parser, p, p ) )
+          if ( p + 1 > limit && limit >= p )
             goto Bad;
         }
 
@@ -525,7 +461,7 @@
     if ( **d == 30 )
     {
       /* binary-coded decimal is truncated to integer */
-      return cff_parse_real( parser, *d, 0, NULL ) >> 16;
+      return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16;
     }
 
     else if ( **d == 255 )
@@ -551,7 +487,7 @@
     }
 
     else
-      return cff_parse_integer( parser, *d );
+      return cff_parse_integer( *d, parser->limit );
   }
 
 
@@ -562,16 +498,34 @@
             FT_Long     scaling )
   {
     if ( **d == 30 )
-      return cff_parse_real( parser, *d, scaling, NULL );
-    else
+      return cff_parse_real( *d, parser->limit, scaling, NULL );
+    else if ( **d == 255 )
     {
-      FT_Long  val = cff_parse_integer( parser, *d );
-
+      FT_Fixed val = ( ( ( (FT_UInt32)*( d[0] + 1 ) << 24 ) |
+                         ( (FT_UInt32)*( d[0] + 2 ) << 16 ) |
+                         ( (FT_UInt32)*( d[0] + 3 ) <<  8 ) |
+                           (FT_UInt32)*( d[0] + 4 )         ) );
 
       if ( scaling )
       {
         if ( FT_ABS( val ) > power_ten_limits[scaling] )
         {
+           FT_TRACE4(( "!!!OVERFLOW:!!!" ));
+           return val > 0 ? 0x7FFFFFFFL : -0x7FFFFFFFL;
+        }
+        val *= power_tens[scaling];
+      }
+      return val;
+    }
+    else
+    {
+      FT_Long  val = cff_parse_integer( *d, parser->limit );
+
+
+      if ( scaling )
+      {
+        if ( ( FT_ABS( val ) << 16 ) > power_ten_limits[scaling] )
+        {
           val = val > 0 ? 0x7FFFFFFFL : -0x7FFFFFFFL;
           goto Overflow;
         }
@@ -600,7 +554,7 @@
 
 
   /* read a floating point number, either integer or real */
-  static FT_Fixed
+  FT_LOCAL_DEF( FT_Fixed )
   cff_parse_fixed( CFF_Parser  parser,
                    FT_Byte**   d )
   {
@@ -630,14 +584,14 @@
     FT_ASSERT( scaling );
 
     if ( **d == 30 )
-      return cff_parse_real( parser, *d, 0, scaling );
+      return cff_parse_real( *d, parser->limit, 0, scaling );
     else
     {
       FT_Long  number;
       FT_Int   integer_length;
 
 
-      number = cff_parse_integer( parser, d[0] );
+      number = cff_parse_integer( *d, parser->limit );
 
       if ( number > 0x7FFFL )
       {
@@ -686,7 +640,7 @@
 
       dict->has_font_matrix = TRUE;
 
-      /* We expect a well-formed font matrix, this is, the matrix elements */
+      /* We expect a well-formed font matrix, that is, the matrix elements */
       /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
       /* loss of precision, we use the magnitude of the largest matrix     */
       /* element to scale all other elements.  The scaling factor is then  */
@@ -1264,11 +1218,8 @@
         FT_Byte*     charstring_base;
         FT_ULong     charstring_len;
 
-        FT_Fixed*      stack;
-        FT_ListNode    node;
-        CFF_T2_String  t2;
-        FT_Fixed       t2_size;
-        FT_Byte*       q;
+        FT_Fixed*  stack;
+        FT_Byte*   q = NULL;
 
 
         charstring_base = ++p;
@@ -1309,39 +1260,18 @@
         /* Now copy the stack data in the temporary decoder object,    */
         /* converting it back to charstring number representations     */
         /* (this is ugly, I know).                                     */
+        /* The maximum required size is 5 bytes per stack element.     */
+        if ( FT_QALLOC( q, (FT_Long)( 2 * sizeof ( FT_ListNode ) ) +
+                           5 * ( decoder.top - decoder.stack ) ) )
+          goto Exit;
 
-        node = (FT_ListNode)memory->alloc( memory,
-                                           sizeof ( FT_ListNodeRec ) );
-        if ( !node )
-          goto Out_Of_Memory_Error;
+        FT_List_Add( &parser->t2_strings, (FT_ListNode)q );
 
-        FT_List_Add( &parser->t2_strings, node );
+        q += 2 * sizeof ( FT_ListNode );
 
-        t2 = (CFF_T2_String)memory->alloc( memory,
-                                           sizeof ( CFF_T2_StringRec ) );
-        if ( !t2 )
-          goto Out_Of_Memory_Error;
-
-        node->data = t2;
-
-        /* `5' is the conservative upper bound of required bytes per stack */
-        /* element.                                                        */
-
-        t2_size = 5 * ( decoder.top - decoder.stack );
-
-        q = (FT_Byte*)memory->alloc( memory, t2_size );
-        if ( !q )
-          goto Out_Of_Memory_Error;
-
-        t2->start = q;
-        t2->limit = q + t2_size;
-
-        stack = decoder.stack;
-
-        while ( stack < decoder.top )
+        for ( stack = decoder.stack; stack < decoder.top; stack++ )
         {
-          FT_ULong  num;
-          FT_Bool   neg;
+          FT_Long  num = *stack;
 
 
           if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
@@ -1349,69 +1279,37 @@
 
           *parser->top++ = q;
 
-          if ( *stack < 0 )
-          {
-            num = (FT_ULong)NEG_LONG( *stack );
-            neg = 1;
-          }
-          else
-          {
-            num = (FT_ULong)*stack;
-            neg = 0;
-          }
-
           if ( num & 0xFFFFU )
           {
-            if ( neg )
-              num = (FT_ULong)-num;
-
             *q++ = 255;
-            *q++ = ( num & 0xFF000000U ) >> 24;
-            *q++ = ( num & 0x00FF0000U ) >> 16;
-            *q++ = ( num & 0x0000FF00U ) >>  8;
-            *q++ =   num & 0x000000FFU;
+            *q++ = (FT_Byte)( ( num >> 24 ) & 0xFF );
+            *q++ = (FT_Byte)( ( num >> 16 ) & 0xFF );
+            *q++ = (FT_Byte)( ( num >>  8 ) & 0xFF );
+            *q++ = (FT_Byte)( ( num       ) & 0xFF );
           }
           else
           {
             num >>= 16;
 
-            if ( neg )
+            if ( -107 <= num && num <= 107 )
+              *q++ = (FT_Byte)( num + 139 );
+            else if ( 108 <= num && num <= 1131 )
             {
-              if ( num <= 107 )
-                *q++ = (FT_Byte)( 139 - num );
-              else if ( num <= 1131 )
-              {
-                *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 );
-                *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
-              }
-              else
-              {
-                num = (FT_ULong)-num;
-
-                *q++ = 28;
-                *q++ = (FT_Byte)( num >> 8 );
-                *q++ = (FT_Byte)( num & 0xFF );
-              }
+              *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 );
+              *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
+            }
+            else if ( -1131 <= num && num <= -108 )
+            {
+              *q++ = (FT_Byte)( ( ( -num - 108 ) >> 8 ) + 251 );
+              *q++ = (FT_Byte)( ( -num - 108) & 0xFF );
             }
             else
             {
-              if ( num <= 107 )
-                *q++ = (FT_Byte)( num + 139 );
-              else if ( num <= 1131 )
-              {
-                *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 );
-                *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
-              }
-              else
-              {
-                *q++ = 28;
-                *q++ = (FT_Byte)( num >> 8 );
-                *q++ = (FT_Byte)( num & 0xFF );
-              }
+              *q++ = 28;
+              *q++ = (FT_Byte)( num >> 8 );
+              *q++ = (FT_Byte)( num & 0xFF );
             }
           }
-
-          stack++;
         }
       }
 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
@@ -1598,12 +1496,6 @@
   Exit:
     return error;
 
-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-  Out_Of_Memory_Error:
-    error = FT_THROW( Out_Of_Memory );
-    goto Exit;
-#endif
-
   Stack_Overflow:
     error = FT_THROW( Invalid_Argument );
     goto Exit;
diff --git a/src/cff/cffparse.h b/src/cff/cffparse.h
index 58d59fa..418caac 100644
--- a/src/cff/cffparse.h
+++ b/src/cff/cffparse.h
@@ -76,6 +76,10 @@
   cff_parse_num( CFF_Parser  parser,
                  FT_Byte**   d );
 
+  FT_LOCAL( FT_Fixed )
+  cff_parse_fixed( CFF_Parser  parser,
+                   FT_Byte**   d );
+
   FT_LOCAL( FT_Error )
   cff_parser_init( CFF_Parser  parser,
                    FT_UInt     code,
@@ -133,15 +137,6 @@
 FT_END_HEADER
 
 
-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-  typedef struct  CFF_T2_String_
-  {
-    FT_Byte*  start;
-    FT_Byte*  limit;
-
-  } CFF_T2_StringRec, *CFF_T2_String;
-#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
-
 #endif /* CFFPARSE_H_ */
 
 
diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c
index ba4b756..eaca765 100644
--- a/src/cid/cidgload.c
+++ b/src/cid/cidgload.c
@@ -40,6 +40,117 @@
 #define FT_COMPONENT  cidgload
 
 
+  /*
+   * A helper function to compute FD number (`fd_select`), the offset to the
+   * head of the glyph data (`off1`), and the offset to the and of the glyph
+   * data (`off2`).
+   *
+   * The number how many times `cid_get_offset` is invoked can be controlled
+   * by the number of non-NULL arguments.  If `fd_select` is non-NULL but
+   * `off1` and `off2` are NULL, `cid_get_offset` is invoked only for
+   * `fd_select`; `off1` and `off2` are not validated.
+   *
+   */
+  FT_LOCAL_DEF( FT_Error )
+  cid_compute_fd_and_offsets( CID_Face   face,
+                              FT_UInt    glyph_index,
+                              FT_ULong*  fd_select_p,
+                              FT_ULong*  off1_p,
+                              FT_ULong*  off2_p )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+    CID_FaceInfo  cid       = &face->cid;
+    FT_Stream     stream    =  face->cid_stream;
+    FT_UInt       entry_len = cid->fd_bytes + cid->gd_bytes;
+
+    FT_Byte*  p;
+    FT_Bool   need_frame_exit = 0;
+    FT_ULong  fd_select, off1, off2;
+
+
+    /* For ordinary fonts, read the CID font dictionary index */
+    /* and charstring offset from the CIDMap.                 */
+
+    if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
+                         glyph_index * entry_len )               ||
+         FT_FRAME_ENTER( 2 * entry_len )                         )
+      goto Exit;
+
+    need_frame_exit = 1;
+
+    p         = (FT_Byte*)stream->cursor;
+    fd_select = cid_get_offset( &p, cid->fd_bytes );
+    off1      = cid_get_offset( &p, cid->gd_bytes );
+
+    p    += cid->fd_bytes;
+    off2  = cid_get_offset( &p, cid->gd_bytes );
+
+    if ( fd_select_p )
+      *fd_select_p = fd_select;
+    if ( off1_p )
+      *off1_p = off1;
+    if ( off2_p )
+      *off2_p = off2;
+
+    if ( fd_select >= cid->num_dicts )
+    {
+      /*
+       * fd_select == 0xFF is often used to indicate that the CID
+       * has no charstring to be rendered, similar to GID = 0xFFFF
+       * in TrueType fonts.
+       */
+      if ( ( cid->fd_bytes == 1 && fd_select == 0xFFU   ) ||
+           ( cid->fd_bytes == 2 && fd_select == 0xFFFFU ) )
+      {
+        FT_TRACE1(( "cid_load_glyph: fail for glyph index %d:\n",
+                    glyph_index ));
+        FT_TRACE1(( "                FD number %ld is the maximum\n",
+                    fd_select ));
+        FT_TRACE1(( "                integer fitting into %d byte%s\n",
+                    cid->fd_bytes, cid->fd_bytes == 1 ? "" : "s" ));
+      }
+      else
+      {
+        FT_TRACE0(( "cid_load_glyph: fail for glyph index %d:\n",
+                    glyph_index ));
+        FT_TRACE0(( "                FD number %ld is larger\n",
+                    fd_select ));
+        FT_TRACE0(( "                than number of dictionaries (%d)\n",
+                    cid->num_dicts ));
+      }
+
+      error = FT_THROW( Invalid_Offset );
+      goto Exit;
+    }
+    else if ( off2 > stream->size )
+    {
+      FT_TRACE0(( "cid_load_glyph: fail for glyph index %d:\n",
+                  glyph_index ));
+      FT_TRACE0(( "               end of the glyph data\n" ));
+      FT_TRACE0(( "               is beyond the data stream\n" ));
+
+      error = FT_THROW( Invalid_Offset );
+      goto Exit;
+    }
+    else if ( off1 > off2 )
+    {
+      FT_TRACE0(( "cid_load_glyph: fail for glyph index %d:\n",
+                  glyph_index ));
+      FT_TRACE0(( "                the end position of glyph data\n" ));
+      FT_TRACE0(( "                is set before the start position\n" ));
+
+      error = FT_THROW( Invalid_Offset );
+    }
+
+    Exit:
+      if ( need_frame_exit )
+        FT_FRAME_EXIT();
+
+    return error;
+  }
+
+
   FT_CALLBACK_DEF( FT_Error )
   cid_load_glyph( T1_Decoder  decoder,
                   FT_UInt     glyph_index )
@@ -97,35 +208,15 @@
     else
 
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
-
-    /* For ordinary fonts read the CID font dictionary index */
-    /* and charstring offset from the CIDMap.                */
     {
-      FT_UInt   entry_len = cid->fd_bytes + cid->gd_bytes;
       FT_ULong  off1, off2;
 
 
-      if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
-                           glyph_index * entry_len )               ||
-           FT_FRAME_ENTER( 2 * entry_len )                         )
+      error = cid_compute_fd_and_offsets( face, glyph_index,
+                                          &fd_select, &off1, &off2 );
+      if ( error )
         goto Exit;
 
-      p         = (FT_Byte*)stream->cursor;
-      fd_select = cid_get_offset( &p, cid->fd_bytes );
-      off1      = cid_get_offset( &p, cid->gd_bytes );
-      p        += cid->fd_bytes;
-      off2      = cid_get_offset( &p, cid->gd_bytes );
-      FT_FRAME_EXIT();
-
-      if ( fd_select >= cid->num_dicts ||
-           off2 > stream->size         ||
-           off1 > off2                 )
-      {
-        FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" ));
-        error = FT_THROW( Invalid_Offset );
-        goto Exit;
-      }
-
       glyph_length = off2 - off1;
 
       if ( glyph_length == 0                             ||
@@ -161,7 +252,9 @@
       cs_offset = decoder->lenIV >= 0 ? (FT_UInt)decoder->lenIV : 0;
       if ( cs_offset > glyph_length )
       {
-        FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" ));
+        FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
+                    "offset to the charstring is beyond glyph length\n",
+                    glyph_index ));
         error = FT_THROW( Invalid_Offset );
         goto Exit;
       }
diff --git a/src/cid/cidgload.h b/src/cid/cidgload.h
index 97954d4..edd6229 100644
--- a/src/cid/cidgload.h
+++ b/src/cid/cidgload.h
@@ -42,6 +42,14 @@
                        FT_Int32      load_flags );
 
 
+  FT_LOCAL( FT_Error )
+  cid_compute_fd_and_offsets( CID_Face   face,
+                              FT_UInt    glyph_index,
+                              FT_ULong*  fd_select_p,
+                              FT_ULong*  off1_p,
+                              FT_ULong*  off2_p );
+
+
 FT_END_HEADER
 
 #endif /* CIDGLOAD_H_ */
diff --git a/src/cid/cidload.c b/src/cid/cidload.c
index 26daa5d..a7da8ea 100644
--- a/src/cid/cidload.c
+++ b/src/cid/cidload.c
@@ -155,23 +155,24 @@
 
 
   FT_CALLBACK_DEF( void )
-  cid_parse_font_matrix( CID_Face     face,
-                         CID_Parser*  parser )
+  cid_parse_font_matrix( FT_Face  face,     /* CID_Face */
+                         void*    parser_ )
   {
+    CID_Face      cidface = (CID_Face)face;
+    CID_Parser*   parser  = (CID_Parser*)parser_;
     CID_FaceDict  dict;
-    FT_Face       root = (FT_Face)&face->root;
     FT_Fixed      temp[6];
     FT_Fixed      temp_scale;
 
 
-    if ( parser->num_dict < face->cid.num_dicts )
+    if ( parser->num_dict < cidface->cid.num_dicts )
     {
       FT_Matrix*  matrix;
       FT_Vector*  offset;
       FT_Int      result;
 
 
-      dict   = face->cid.font_dicts + parser->num_dict;
+      dict   = cidface->cid.font_dicts + parser->num_dict;
       matrix = &dict->font_matrix;
       offset = &dict->font_offset;
 
@@ -204,7 +205,7 @@
       if ( temp_scale != 0x10000L )
       {
         /* set units per EM based on FontMatrix values */
-        root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
+        face->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
 
         temp[0] = FT_DivFix( temp[0], temp_scale );
         temp[1] = FT_DivFix( temp[1], temp_scale );
@@ -237,13 +238,15 @@
 
 
   FT_CALLBACK_DEF( void )
-  parse_fd_array( CID_Face     face,
-                  CID_Parser*  parser )
+  parse_fd_array( FT_Face  face,     /* CID_Face */
+                  void*    parser_ )
   {
-    CID_FaceInfo  cid    = &face->cid;
-    FT_Memory     memory = face->root.memory;
-    FT_Stream     stream = parser->stream;
-    FT_Error      error  = FT_Err_Ok;
+    CID_Face      cidface = (CID_Face)face;
+    CID_Parser*   parser  = (CID_Parser*)parser_;
+    CID_FaceInfo  cid     = &cidface->cid;
+    FT_Memory     memory  = FT_FACE_MEMORY( face );
+    FT_Stream     stream  = parser->stream;
+    FT_Error      error   = FT_Err_Ok;
     FT_Long       num_dicts, max_dicts;
 
 
@@ -313,18 +316,20 @@
 
   /* By mistake, `expansion_factor' appears both in PS_PrivateRec */
   /* and CID_FaceDictRec (both are public header files and can't  */
-  /* changed).  We simply copy the value.                         */
+  /* be thus changed).  We simply copy the value.                 */
 
   FT_CALLBACK_DEF( void )
-  parse_expansion_factor( CID_Face     face,
-                          CID_Parser*  parser )
+  parse_expansion_factor( FT_Face  face,    /* CID_Face */
+                          void*    parser_ )
   {
+    CID_Face      cidface = (CID_Face)face;
+    CID_Parser*   parser  = (CID_Parser*)parser_;
     CID_FaceDict  dict;
 
 
-    if ( parser->num_dict < face->cid.num_dicts )
+    if ( parser->num_dict < cidface->cid.num_dicts )
     {
-      dict = face->cid.font_dicts + parser->num_dict;
+      dict = cidface->cid.font_dicts + parser->num_dict;
 
       dict->expansion_factor              = cid_parser_to_fixed( parser, 0 );
       dict->private_dict.expansion_factor = dict->expansion_factor;
@@ -341,11 +346,15 @@
   /* to catch it for producing better trace output.                */
 
   FT_CALLBACK_DEF( void )
-  parse_font_name( CID_Face     face,
-                   CID_Parser*  parser )
+  parse_font_name( FT_Face  face,     /* CID_Face */
+                   void*    parser_ )
   {
 #ifdef FT_DEBUG_LEVEL_TRACE
-    if ( parser->num_dict < face->cid.num_dicts )
+    CID_Face      cidface = (CID_Face)face;
+    CID_Parser*   parser  = (CID_Parser*)parser_;
+
+
+    if ( parser->num_dict < cidface->cid.num_dicts )
     {
       T1_TokenRec  token;
       FT_UInt      len;
@@ -361,7 +370,7 @@
     }
 #else
     FT_UNUSED( face );
-    FT_UNUSED( parser );
+    FT_UNUSED( parser_ );
 #endif
 
     return;
diff --git a/src/cid/cidobjs.c b/src/cid/cidobjs.c
index 06b2139..f698a41 100644
--- a/src/cid/cidobjs.c
+++ b/src/cid/cidobjs.c
@@ -69,8 +69,7 @@
       FT_Module  module;
 
 
-      module = FT_Get_Module( slot->face->driver->root.library,
-                              "pshinter" );
+      module = FT_Get_Module( slot->library, "pshinter" );
       if ( module )
       {
         T1_Hints_Funcs  funcs;
@@ -268,7 +267,8 @@
    *
    * @Input:
    *   stream ::
-   *     The source font stream.
+   *     Dummy argument for compatibility with the `FT_Face_InitFunc` API.
+   *     Ignored.  The stream should be passed through `face->root.stream`.
    *
    *   face_index ::
    *     The index of the font face in the resource.
@@ -375,6 +375,14 @@
       if ( info->is_fixed_pitch )
         cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
 
+      /*
+       * For the sfnt-wrapped CID fonts for MacOS, currently,
+       * its `cmap' tables are ignored, and the content in
+       * its `CID ' table is treated the same as naked CID-keyed
+       * font.  See ft_lookup_PS_in_sfnt_stream().
+       */
+      cidface->face_flags |= FT_FACE_FLAG_CID_KEYED;
+
       /* XXX: TODO: add kerning with .afm support */
 
       /* get style name -- be careful, some broken fonts only */
diff --git a/src/cid/cidparse.c b/src/cid/cidparse.c
index 16889db..171a886 100644
--- a/src/cid/cidparse.c
+++ b/src/cid/cidparse.c
@@ -214,18 +214,24 @@
            cur <= limit - STARTDATA_LEN                            &&
            ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 )
       {
-        if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
+        T1_TokenRec  type_token;
+        FT_Long      binary_length;
+
+
+        parser->root.cursor = arg1;
+        cid_parser_to_token( parser, &type_token );
+        if ( type_token.limit - type_token.start == 5              &&
+             ft_memcmp( (char*)type_token.start, "(Hex)", 5 ) == 0 )
         {
-          FT_Long  tmp = ft_strtol( (const char *)arg2, NULL, 10 );
-
-
-          if ( tmp < 0 )
+          parser->root.cursor = arg2;
+          binary_length = cid_parser_to_int( parser );
+          if ( binary_length < 0 )
           {
             FT_ERROR(( "cid_parser_new: invalid length of hex data\n" ));
             error = FT_THROW( Invalid_File_Format );
           }
           else
-            parser->binary_length = (FT_ULong)tmp;
+            parser->binary_length = (FT_ULong)binary_length;
         }
 
         goto Exit;
diff --git a/src/cid/cidriver.c b/src/cid/cidriver.c
index f749923..99e7b11 100644
--- a/src/cid/cidriver.c
+++ b/src/cid/cidriver.c
@@ -48,10 +48,11 @@
    *
    */
 
-  static const char*
-  cid_get_postscript_name( CID_Face  face )
+  FT_CALLBACK_DEF( const char* )
+  cid_get_postscript_name( FT_Face  face )    /* CID_Face */
   {
-    const char*  result = face->cid.cid_font_name;
+    CID_Face     cidface = (CID_Face)face;
+    const char*  result  = cidface->cid.cid_font_name;
 
 
     if ( result && result[0] == '/' )
@@ -72,34 +73,36 @@
    *
    */
 
-  static FT_Error
-  cid_ps_get_font_info( FT_Face          face,
+  FT_CALLBACK_DEF( FT_Error )
+  cid_ps_get_font_info( FT_Face          face,        /* CID_Face */
                         PS_FontInfoRec*  afont_info )
   {
-    *afont_info = ((CID_Face)face)->cid.font_info;
+    *afont_info = ( (CID_Face)face )->cid.font_info;
 
     return FT_Err_Ok;
   }
 
-  static FT_Error
-  cid_ps_get_font_extra( FT_Face          face,
-                        PS_FontExtraRec*  afont_extra )
+
+  FT_CALLBACK_DEF( FT_Error )
+  cid_ps_get_font_extra( FT_Face           face,         /* CID_Face */
+                         PS_FontExtraRec*  afont_extra )
   {
-    *afont_extra = ((CID_Face)face)->font_extra;
+    *afont_extra = ( (CID_Face)face )->font_extra;
 
     return FT_Err_Ok;
   }
 
+
   static const FT_Service_PsInfoRec  cid_service_ps_info =
   {
-    (PS_GetFontInfoFunc)   cid_ps_get_font_info,   /* ps_get_font_info    */
-    (PS_GetFontExtraFunc)  cid_ps_get_font_extra,  /* ps_get_font_extra   */
+    cid_ps_get_font_info,   /* PS_GetFontInfoFunc    ps_get_font_info    */
+    cid_ps_get_font_extra,  /* PS_GetFontExtraFunc   ps_get_font_extra   */
     /* unsupported with CID fonts */
-    (PS_HasGlyphNamesFunc) NULL,                   /* ps_has_glyph_names  */
+    NULL,                   /* PS_HasGlyphNamesFunc  ps_has_glyph_names  */
     /* unsupported                */
-    (PS_GetFontPrivateFunc)NULL,                   /* ps_get_font_private */
+    NULL,                   /* PS_GetFontPrivateFunc ps_get_font_private */
     /* not implemented            */
-    (PS_GetFontValueFunc)  NULL                    /* ps_get_font_value   */
+    NULL                    /* PS_GetFontValueFunc   ps_get_font_value   */
   };
 
 
@@ -107,13 +110,14 @@
    * CID INFO SERVICE
    *
    */
-  static FT_Error
-  cid_get_ros( CID_Face      face,
+  FT_CALLBACK_DEF( FT_Error )
+  cid_get_ros( FT_Face       face,        /* CID_Face */
                const char*  *registry,
                const char*  *ordering,
                FT_Int       *supplement )
   {
-    CID_FaceInfo  cid = &face->cid;
+    CID_Face      cidface = (CID_Face)face;
+    CID_FaceInfo  cid     = &cidface->cid;
 
 
     if ( registry )
@@ -129,32 +133,48 @@
   }
 
 
-  static FT_Error
-  cid_get_is_cid( CID_Face  face,
+  FT_CALLBACK_DEF( FT_Error )
+  cid_get_is_cid( FT_Face   face,    /* CID_Face */
                   FT_Bool  *is_cid )
   {
     FT_Error  error = FT_Err_Ok;
     FT_UNUSED( face );
 
 
+    /*
+     * XXX: If the ROS is Adobe-Identity-H or -V,
+     * the font has no reliable information about
+     * its glyph collection.  Should we not set
+     * *is_cid in such cases?
+     */
     if ( is_cid )
-      *is_cid = 1; /* cid driver is only used for CID keyed fonts */
+      *is_cid = 1;
 
     return error;
   }
 
 
-  static FT_Error
-  cid_get_cid_from_glyph_index( CID_Face  face,
+  FT_CALLBACK_DEF( FT_Error )
+  cid_get_cid_from_glyph_index( FT_Face   face,        /* CID_Face */
                                 FT_UInt   glyph_index,
                                 FT_UInt  *cid )
   {
-    FT_Error  error = FT_Err_Ok;
-    FT_UNUSED( face );
+    FT_Error  error   = FT_Err_Ok;
+    CID_Face  cidface = (CID_Face)face;
 
 
-    if ( cid )
-      *cid = glyph_index; /* identity mapping */
+    /*
+     * Currently, FreeType does not support incrementally-defined, CID-keyed
+     * fonts that store the glyph description data in a `/GlyphDirectory`
+     * array or dictionary.  Fonts loaded by the incremental loading feature
+     * are thus not handled here.
+     */
+    error = cid_compute_fd_and_offsets( cidface, glyph_index,
+                                        NULL, NULL, NULL );
+    if ( error )
+      *cid = 0;
+    else
+      *cid = glyph_index;
 
     return error;
   }
@@ -162,12 +182,12 @@
 
   static const FT_Service_CIDRec  cid_service_cid_info =
   {
-    (FT_CID_GetRegistryOrderingSupplementFunc)
-      cid_get_ros,                             /* get_ros                  */
-    (FT_CID_GetIsInternallyCIDKeyedFunc)
-      cid_get_is_cid,                          /* get_is_cid               */
-    (FT_CID_GetCIDFromGlyphIndexFunc)
-      cid_get_cid_from_glyph_index             /* get_cid_from_glyph_index */
+    cid_get_ros,
+      /* FT_CID_GetRegistryOrderingSupplementFunc get_ros                  */
+    cid_get_is_cid,
+      /* FT_CID_GetIsInternallyCIDKeyedFunc       get_is_cid               */
+    cid_get_cid_from_glyph_index
+      /* FT_CID_GetCIDFromGlyphIndexFunc          get_cid_from_glyph_index */
   };
 
 
@@ -179,9 +199,9 @@
   FT_DEFINE_SERVICE_PROPERTIESREC(
     cid_service_properties,
 
-    (FT_Properties_SetFunc)ps_property_set,      /* set_property */
-    (FT_Properties_GetFunc)ps_property_get )     /* get_property */
-
+    ps_property_set,  /* FT_Properties_SetFunc set_property */
+    ps_property_get   /* FT_Properties_GetFunc get_property */
+  )
 
   /*
    * SERVICE LIST
@@ -209,7 +229,6 @@
   }
 
 
-
   FT_CALLBACK_TABLE_DEF
   const FT_Driver_ClassRec  t1cid_driver_class =
   {
diff --git a/src/dlg/dlgwrap.c b/src/dlg/dlgwrap.c
index 271241f..e9dc341 100644
--- a/src/dlg/dlgwrap.c
+++ b/src/dlg/dlgwrap.c
@@ -25,7 +25,7 @@
 #include "dlg.c"
 #else
   /* ANSI C doesn't like empty source files */
-  typedef int  _dlg_dummy;
+  typedef int  dlg_dummy_;
 #endif
 
 
diff --git a/src/gxvalid/gxvfgen.c b/src/gxvalid/gxvfgen.c
index 1153542..cf98bb3 100644
--- a/src/gxvalid/gxvfgen.c
+++ b/src/gxvalid/gxvfgen.c
@@ -97,7 +97,8 @@
 #define EMPTYFEAT {0, 0, {NULL}}
 
 
-  static GX_Feature_RegistryRec featreg_table[] = {
+  static GX_Feature_RegistryRec featreg_table[] =
+  {
     {                                       /* 0 */
       "All Typographic Features",
       0,
diff --git a/src/gzip/README.freetype b/src/gzip/README.freetype
index e0c8ced..76298b0 100644
--- a/src/gzip/README.freetype
+++ b/src/gzip/README.freetype
@@ -1,7 +1,7 @@
 Name: zlib
 Short Name: zlib
 URL: http://zlib.net/
-Version: 1.2.12
+Version: 1.2.13
 License: see `zlib.h`
 
 Description:
diff --git a/src/gzip/ftgzip.c b/src/gzip/ftgzip.c
index 48da6ff..ca6a2aa 100644
--- a/src/gzip/ftgzip.c
+++ b/src/gzip/ftgzip.c
@@ -70,10 +70,9 @@
   /* so that configuration with `FT_CONFIG_OPTION_SYSTEM_ZLIB' might   */
   /* include the wrong `zconf.h' file, leading to errors.              */
 
-#if defined( __GNUC__ ) ||  defined( __clang__ )
 #define ZEXPORT
-#define ZEXTERN      static
-#endif
+  /* prevent zlib functions from being visible outside their object files */
+#define ZEXTERN  static
 
 #define HAVE_MEMCPY  1
 #define Z_SOLO       1
diff --git a/src/gzip/infback.c b/src/gzip/infback.c
deleted file mode 100644
index 264c14e..0000000
--- a/src/gzip/infback.c
+++ /dev/null
@@ -1,644 +0,0 @@
-/* infback.c -- inflate using a call-back interface
- * Copyright (C) 1995-2022 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
-   This code is largely copied from inflate.c.  Normally either infback.o or
-   inflate.o would be linked into an application--not both.  The interface
-   with inffast.c is retained so that optimized assembler-coded versions of
-   inflate_fast() can be used with either inflate.c or infback.c.
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-/* function prototypes */
-local void fixedtables OF((struct inflate_state FAR *state));
-
-/*
-   strm provides memory allocation functions in zalloc and zfree, or
-   Z_NULL to use the library memory allocation functions.
-
-   windowBits is in the range 8..15, and window is a user-supplied
-   window and output buffer that is 2**windowBits bytes.
- */
-int ZEXPORT inflateBackInit_(
-    z_streamp strm,
-    int windowBits,
-    unsigned char FAR *window,
-    const char *version,
-    int stream_size)
-{
-    struct inflate_state FAR *state;
-
-    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
-        stream_size != (int)(sizeof(z_stream)))
-        return Z_VERSION_ERROR;
-    if (strm == Z_NULL || window == Z_NULL ||
-        windowBits < 8 || windowBits > 15)
-        return Z_STREAM_ERROR;
-    strm->msg = Z_NULL;                 /* in case we return an error */
-    if (strm->zalloc == (alloc_func)0) {
-#ifdef Z_SOLO
-        return Z_STREAM_ERROR;
-#else
-        strm->zalloc = zcalloc;
-        strm->opaque = (voidpf)0;
-#endif
-    }
-    if (strm->zfree == (free_func)0)
-#ifdef Z_SOLO
-        return Z_STREAM_ERROR;
-#else
-    strm->zfree = zcfree;
-#endif
-    state = (struct inflate_state FAR *)ZALLOC(strm, 1,
-                                               sizeof(struct inflate_state));
-    if (state == Z_NULL) return Z_MEM_ERROR;
-    Tracev((stderr, "inflate: allocated\n"));
-    strm->state = (struct internal_state FAR *)state;
-    state->dmax = 32768U;
-    state->wbits = (uInt)windowBits;
-    state->wsize = 1U << windowBits;
-    state->window = window;
-    state->wnext = 0;
-    state->whave = 0;
-    state->sane = 1;
-    return Z_OK;
-}
-
-/*
-   Return state with length and distance decoding tables and index sizes set to
-   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
-   If BUILDFIXED is defined, then instead this routine builds the tables the
-   first time it's called, and returns those tables the first time and
-   thereafter.  This reduces the size of the code by about 2K bytes, in
-   exchange for a little execution time.  However, BUILDFIXED should not be
-   used for threaded applications, since the rewriting of the tables and virgin
-   may not be thread-safe.
- */
-local void fixedtables(
-    struct inflate_state FAR *state)
-{
-#ifdef BUILDFIXED
-    static int virgin = 1;
-    static code *lenfix, *distfix;
-    static code fixed[544];
-
-    /* build fixed huffman tables if first call (may not be thread safe) */
-    if (virgin) {
-        unsigned sym, bits;
-        static code *next;
-
-        /* literal/length table */
-        sym = 0;
-        while (sym < 144) state->lens[sym++] = 8;
-        while (sym < 256) state->lens[sym++] = 9;
-        while (sym < 280) state->lens[sym++] = 7;
-        while (sym < 288) state->lens[sym++] = 8;
-        next = fixed;
-        lenfix = next;
-        bits = 9;
-        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
-
-        /* distance table */
-        sym = 0;
-        while (sym < 32) state->lens[sym++] = 5;
-        distfix = next;
-        bits = 5;
-        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
-
-        /* do this just once */
-        virgin = 0;
-    }
-#else /* !BUILDFIXED */
-#   include "inffixed.h"
-#endif /* BUILDFIXED */
-    state->lencode = lenfix;
-    state->lenbits = 9;
-    state->distcode = distfix;
-    state->distbits = 5;
-}
-
-/* Macros for inflateBack(): */
-
-/* Load returned state from inflate_fast() */
-#define LOAD() \
-    do { \
-        put = strm->next_out; \
-        left = strm->avail_out; \
-        next = strm->next_in; \
-        have = strm->avail_in; \
-        hold = state->hold; \
-        bits = state->bits; \
-    } while (0)
-
-/* Set state from registers for inflate_fast() */
-#define RESTORE() \
-    do { \
-        strm->next_out = put; \
-        strm->avail_out = left; \
-        strm->next_in = next; \
-        strm->avail_in = have; \
-        state->hold = hold; \
-        state->bits = bits; \
-    } while (0)
-
-/* Clear the input bit accumulator */
-#define INITBITS() \
-    do { \
-        hold = 0; \
-        bits = 0; \
-    } while (0)
-
-/* Assure that some input is available.  If input is requested, but denied,
-   then return a Z_BUF_ERROR from inflateBack(). */
-#define PULL() \
-    do { \
-        if (have == 0) { \
-            have = in(in_desc, &next); \
-            if (have == 0) { \
-                next = Z_NULL; \
-                ret = Z_BUF_ERROR; \
-                goto inf_leave; \
-            } \
-        } \
-    } while (0)
-
-/* Get a byte of input into the bit accumulator, or return from inflateBack()
-   with an error if there is no input available. */
-#define PULLBYTE() \
-    do { \
-        PULL(); \
-        have--; \
-        hold += (unsigned long)(*next++) << bits; \
-        bits += 8; \
-    } while (0)
-
-/* Assure that there are at least n bits in the bit accumulator.  If there is
-   not enough available input to do that, then return from inflateBack() with
-   an error. */
-#define NEEDBITS(n) \
-    do { \
-        while (bits < (unsigned)(n)) \
-            PULLBYTE(); \
-    } while (0)
-
-/* Return the low n bits of the bit accumulator (n < 16) */
-#define BITS(n) \
-    ((unsigned)hold & ((1U << (n)) - 1))
-
-/* Remove n bits from the bit accumulator */
-#define DROPBITS(n) \
-    do { \
-        hold >>= (n); \
-        bits -= (unsigned)(n); \
-    } while (0)
-
-/* Remove zero to seven bits as needed to go to a byte boundary */
-#define BYTEBITS() \
-    do { \
-        hold >>= bits & 7; \
-        bits -= bits & 7; \
-    } while (0)
-
-/* Assure that some output space is available, by writing out the window
-   if it's full.  If the write fails, return from inflateBack() with a
-   Z_BUF_ERROR. */
-#define ROOM() \
-    do { \
-        if (left == 0) { \
-            put = state->window; \
-            left = state->wsize; \
-            state->whave = left; \
-            if (out(out_desc, put, left)) { \
-                ret = Z_BUF_ERROR; \
-                goto inf_leave; \
-            } \
-        } \
-    } while (0)
-
-/*
-   strm provides the memory allocation functions and window buffer on input,
-   and provides information on the unused input on return.  For Z_DATA_ERROR
-   returns, strm will also provide an error message.
-
-   in() and out() are the call-back input and output functions.  When
-   inflateBack() needs more input, it calls in().  When inflateBack() has
-   filled the window with output, or when it completes with data in the
-   window, it calls out() to write out the data.  The application must not
-   change the provided input until in() is called again or inflateBack()
-   returns.  The application must not change the window/output buffer until
-   inflateBack() returns.
-
-   in() and out() are called with a descriptor parameter provided in the
-   inflateBack() call.  This parameter can be a structure that provides the
-   information required to do the read or write, as well as accumulated
-   information on the input and output such as totals and check values.
-
-   in() should return zero on failure.  out() should return non-zero on
-   failure.  If either in() or out() fails, than inflateBack() returns a
-   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
-   was in() or out() that caused in the error.  Otherwise,  inflateBack()
-   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
-   error, or Z_MEM_ERROR if it could not allocate memory for the state.
-   inflateBack() can also return Z_STREAM_ERROR if the input parameters
-   are not correct, i.e. strm is Z_NULL or the state was not initialized.
- */
-int ZEXPORT inflateBack(
-    z_streamp strm,
-    in_func in,
-    void FAR *in_desc,
-    out_func out,
-    void FAR *out_desc)
-{
-    struct inflate_state FAR *state;
-    z_const unsigned char FAR *next;    /* next input */
-    unsigned char FAR *put;     /* next output */
-    unsigned have, left;        /* available input and output */
-    unsigned long hold;         /* bit buffer */
-    unsigned bits;              /* bits in bit buffer */
-    unsigned copy;              /* number of stored or match bytes to copy */
-    unsigned char FAR *from;    /* where to copy match bytes from */
-    code here;                  /* current decoding table entry */
-    code last;                  /* parent table entry */
-    unsigned len;               /* length to copy for repeats, bits to drop */
-    int ret;                    /* return code */
-    static const unsigned short order[19] = /* permutation of code lengths */
-        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
-    /* Check that the strm exists and that the state was initialized */
-    if (strm == Z_NULL || strm->state == Z_NULL)
-        return Z_STREAM_ERROR;
-    state = (struct inflate_state FAR *)strm->state;
-
-    /* Reset the state */
-    strm->msg = Z_NULL;
-    state->mode = TYPE;
-    state->last = 0;
-    state->whave = 0;
-    next = strm->next_in;
-    have = next != Z_NULL ? strm->avail_in : 0;
-    hold = 0;
-    bits = 0;
-    put = state->window;
-    left = state->wsize;
-
-    /* Inflate until end of block marked as last */
-    for (;;)
-        switch (state->mode) {
-        case TYPE:
-            /* determine and dispatch block type */
-            if (state->last) {
-                BYTEBITS();
-                state->mode = DONE;
-                break;
-            }
-            NEEDBITS(3);
-            state->last = BITS(1);
-            DROPBITS(1);
-            switch (BITS(2)) {
-            case 0:                             /* stored block */
-                Tracev((stderr, "inflate:     stored block%s\n",
-                        state->last ? " (last)" : ""));
-                state->mode = STORED;
-                break;
-            case 1:                             /* fixed block */
-                fixedtables(state);
-                Tracev((stderr, "inflate:     fixed codes block%s\n",
-                        state->last ? " (last)" : ""));
-                state->mode = LEN;              /* decode codes */
-                break;
-            case 2:                             /* dynamic block */
-                Tracev((stderr, "inflate:     dynamic codes block%s\n",
-                        state->last ? " (last)" : ""));
-                state->mode = TABLE;
-                break;
-            case 3:
-                strm->msg = (char *)"invalid block type";
-                state->mode = BAD;
-            }
-            DROPBITS(2);
-            break;
-
-        case STORED:
-            /* get and verify stored block length */
-            BYTEBITS();                         /* go to byte boundary */
-            NEEDBITS(32);
-            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
-                strm->msg = (char *)"invalid stored block lengths";
-                state->mode = BAD;
-                break;
-            }
-            state->length = (unsigned)hold & 0xffff;
-            Tracev((stderr, "inflate:       stored length %u\n",
-                    state->length));
-            INITBITS();
-
-            /* copy stored block from input to output */
-            while (state->length != 0) {
-                copy = state->length;
-                PULL();
-                ROOM();
-                if (copy > have) copy = have;
-                if (copy > left) copy = left;
-                zmemcpy(put, next, copy);
-                have -= copy;
-                next += copy;
-                left -= copy;
-                put += copy;
-                state->length -= copy;
-            }
-            Tracev((stderr, "inflate:       stored end\n"));
-            state->mode = TYPE;
-            break;
-
-        case TABLE:
-            /* get dynamic table entries descriptor */
-            NEEDBITS(14);
-            state->nlen = BITS(5) + 257;
-            DROPBITS(5);
-            state->ndist = BITS(5) + 1;
-            DROPBITS(5);
-            state->ncode = BITS(4) + 4;
-            DROPBITS(4);
-#ifndef PKZIP_BUG_WORKAROUND
-            if (state->nlen > 286 || state->ndist > 30) {
-                strm->msg = (char *)"too many length or distance symbols";
-                state->mode = BAD;
-                break;
-            }
-#endif
-            Tracev((stderr, "inflate:       table sizes ok\n"));
-
-            /* get code length code lengths (not a typo) */
-            state->have = 0;
-            while (state->have < state->ncode) {
-                NEEDBITS(3);
-                state->lens[order[state->have++]] = (unsigned short)BITS(3);
-                DROPBITS(3);
-            }
-            while (state->have < 19)
-                state->lens[order[state->have++]] = 0;
-            state->next = state->codes;
-            state->lencode = (code const FAR *)(state->next);
-            state->lenbits = 7;
-            ret = inflate_table(CODES, state->lens, 19, &(state->next),
-                                &(state->lenbits), state->work);
-            if (ret) {
-                strm->msg = (char *)"invalid code lengths set";
-                state->mode = BAD;
-                break;
-            }
-            Tracev((stderr, "inflate:       code lengths ok\n"));
-
-            /* get length and distance code code lengths */
-            state->have = 0;
-            while (state->have < state->nlen + state->ndist) {
-                for (;;) {
-                    here = state->lencode[BITS(state->lenbits)];
-                    if ((unsigned)(here.bits) <= bits) break;
-                    PULLBYTE();
-                }
-                if (here.val < 16) {
-                    DROPBITS(here.bits);
-                    state->lens[state->have++] = here.val;
-                }
-                else {
-                    if (here.val == 16) {
-                        NEEDBITS(here.bits + 2);
-                        DROPBITS(here.bits);
-                        if (state->have == 0) {
-                            strm->msg = (char *)"invalid bit length repeat";
-                            state->mode = BAD;
-                            break;
-                        }
-                        len = (unsigned)(state->lens[state->have - 1]);
-                        copy = 3 + BITS(2);
-                        DROPBITS(2);
-                    }
-                    else if (here.val == 17) {
-                        NEEDBITS(here.bits + 3);
-                        DROPBITS(here.bits);
-                        len = 0;
-                        copy = 3 + BITS(3);
-                        DROPBITS(3);
-                    }
-                    else {
-                        NEEDBITS(here.bits + 7);
-                        DROPBITS(here.bits);
-                        len = 0;
-                        copy = 11 + BITS(7);
-                        DROPBITS(7);
-                    }
-                    if (state->have + copy > state->nlen + state->ndist) {
-                        strm->msg = (char *)"invalid bit length repeat";
-                        state->mode = BAD;
-                        break;
-                    }
-                    while (copy--)
-                        state->lens[state->have++] = (unsigned short)len;
-                }
-            }
-
-            /* handle error breaks in while */
-            if (state->mode == BAD) break;
-
-            /* check for end-of-block code (better have one) */
-            if (state->lens[256] == 0) {
-                strm->msg = (char *)"invalid code -- missing end-of-block";
-                state->mode = BAD;
-                break;
-            }
-
-            /* build code tables -- note: do not change the lenbits or distbits
-               values here (9 and 6) without reading the comments in inftrees.h
-               concerning the ENOUGH constants, which depend on those values */
-            state->next = state->codes;
-            state->lencode = (code const FAR *)(state->next);
-            state->lenbits = 9;
-            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
-                                &(state->lenbits), state->work);
-            if (ret) {
-                strm->msg = (char *)"invalid literal/lengths set";
-                state->mode = BAD;
-                break;
-            }
-            state->distcode = (code const FAR *)(state->next);
-            state->distbits = 6;
-            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
-                            &(state->next), &(state->distbits), state->work);
-            if (ret) {
-                strm->msg = (char *)"invalid distances set";
-                state->mode = BAD;
-                break;
-            }
-            Tracev((stderr, "inflate:       codes ok\n"));
-            state->mode = LEN;
-                /* fallthrough */
-
-        case LEN:
-            /* use inflate_fast() if we have enough input and output */
-            if (have >= 6 && left >= 258) {
-                RESTORE();
-                if (state->whave < state->wsize)
-                    state->whave = state->wsize - left;
-                inflate_fast(strm, state->wsize);
-                LOAD();
-                break;
-            }
-
-            /* get a literal, length, or end-of-block code */
-            for (;;) {
-                here = state->lencode[BITS(state->lenbits)];
-                if ((unsigned)(here.bits) <= bits) break;
-                PULLBYTE();
-            }
-            if (here.op && (here.op & 0xf0) == 0) {
-                last = here;
-                for (;;) {
-                    here = state->lencode[last.val +
-                            (BITS(last.bits + last.op) >> last.bits)];
-                    if ((unsigned)(last.bits + here.bits) <= bits) break;
-                    PULLBYTE();
-                }
-                DROPBITS(last.bits);
-            }
-            DROPBITS(here.bits);
-            state->length = (unsigned)here.val;
-
-            /* process literal */
-            if (here.op == 0) {
-                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
-                        "inflate:         literal '%c'\n" :
-                        "inflate:         literal 0x%02x\n", here.val));
-                ROOM();
-                *put++ = (unsigned char)(state->length);
-                left--;
-                state->mode = LEN;
-                break;
-            }
-
-            /* process end of block */
-            if (here.op & 32) {
-                Tracevv((stderr, "inflate:         end of block\n"));
-                state->mode = TYPE;
-                break;
-            }
-
-            /* invalid code */
-            if (here.op & 64) {
-                strm->msg = (char *)"invalid literal/length code";
-                state->mode = BAD;
-                break;
-            }
-
-            /* length code -- get extra bits, if any */
-            state->extra = (unsigned)(here.op) & 15;
-            if (state->extra != 0) {
-                NEEDBITS(state->extra);
-                state->length += BITS(state->extra);
-                DROPBITS(state->extra);
-            }
-            Tracevv((stderr, "inflate:         length %u\n", state->length));
-
-            /* get distance code */
-            for (;;) {
-                here = state->distcode[BITS(state->distbits)];
-                if ((unsigned)(here.bits) <= bits) break;
-                PULLBYTE();
-            }
-            if ((here.op & 0xf0) == 0) {
-                last = here;
-                for (;;) {
-                    here = state->distcode[last.val +
-                            (BITS(last.bits + last.op) >> last.bits)];
-                    if ((unsigned)(last.bits + here.bits) <= bits) break;
-                    PULLBYTE();
-                }
-                DROPBITS(last.bits);
-            }
-            DROPBITS(here.bits);
-            if (here.op & 64) {
-                strm->msg = (char *)"invalid distance code";
-                state->mode = BAD;
-                break;
-            }
-            state->offset = (unsigned)here.val;
-
-            /* get distance extra bits, if any */
-            state->extra = (unsigned)(here.op) & 15;
-            if (state->extra != 0) {
-                NEEDBITS(state->extra);
-                state->offset += BITS(state->extra);
-                DROPBITS(state->extra);
-            }
-            if (state->offset > state->wsize - (state->whave < state->wsize ?
-                                                left : 0)) {
-                strm->msg = (char *)"invalid distance too far back";
-                state->mode = BAD;
-                break;
-            }
-            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
-
-            /* copy match from window to output */
-            do {
-                ROOM();
-                copy = state->wsize - state->offset;
-                if (copy < left) {
-                    from = put + copy;
-                    copy = left - copy;
-                }
-                else {
-                    from = put - state->offset;
-                    copy = left;
-                }
-                if (copy > state->length) copy = state->length;
-                state->length -= copy;
-                left -= copy;
-                do {
-                    *put++ = *from++;
-                } while (--copy);
-            } while (state->length != 0);
-            break;
-
-        case DONE:
-            /* inflate stream terminated properly */
-            ret = Z_STREAM_END;
-            goto inf_leave;
-
-        case BAD:
-            ret = Z_DATA_ERROR;
-            goto inf_leave;
-
-        default:
-            /* can't happen, but makes compilers happy */
-            ret = Z_STREAM_ERROR;
-            goto inf_leave;
-        }
-
-    /* Write leftover output and return unused input */
-  inf_leave:
-    if (left < state->wsize) {
-        if (out(out_desc, state->window, state->wsize - left) &&
-            ret == Z_STREAM_END)
-            ret = Z_BUF_ERROR;
-    }
-    strm->next_in = next;
-    strm->avail_in = have;
-    return ret;
-}
-
-int ZEXPORT inflateBackEnd(
-    z_streamp strm)
-{
-    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
-        return Z_STREAM_ERROR;
-    ZFREE(strm, strm->state);
-    strm->state = Z_NULL;
-    Tracev((stderr, "inflate: end\n"));
-    return Z_OK;
-}
diff --git a/src/gzip/rules.mk b/src/gzip/rules.mk
index 6feb6f5..c76eacb 100644
--- a/src/gzip/rules.mk
+++ b/src/gzip/rules.mk
@@ -36,25 +36,23 @@
 #
 # All source and header files get loaded by `ftgzip.c' only if SYSTEM_ZLIB
 # is not defined (regardless whether we have a `single' or a `multi' build).
-# However, it doesn't harm if we add everything as a dependency
-# unconditionally.
 #
-GZIP_DRV_SRCS := $(GZIP_DIR)/adler32.c  \
-                 $(GZIP_DIR)/crc32.c    \
-                 $(GZIP_DIR)/crc32.h    \
-                 $(GZIP_DIR)/ftzconf.h  \
-                 $(GZIP_DIR)/infback.c  \
-                 $(GZIP_DIR)/inffast.c  \
-                 $(GZIP_DIR)/inffast.h  \
-                 $(GZIP_DIR)/inffixed.h \
-                 $(GZIP_DIR)/inflate.c  \
-                 $(GZIP_DIR)/inflate.h  \
-                 $(GZIP_DIR)/inftrees.c \
-                 $(GZIP_DIR)/inftrees.h \
-                 $(GZIP_DIR)/zlib.h     \
-                 $(GZIP_DIR)/zutil.c    \
-                 $(GZIP_DIR)/zutil.h
-
+ifeq ($(SYSTEM_ZLIB),)
+  GZIP_DRV_SRCS := $(GZIP_DIR)/adler32.c  \
+                   $(GZIP_DIR)/crc32.c    \
+                   $(GZIP_DIR)/crc32.h    \
+                   $(GZIP_DIR)/ftzconf.h  \
+                   $(GZIP_DIR)/inffast.c  \
+                   $(GZIP_DIR)/inffast.h  \
+                   $(GZIP_DIR)/inffixed.h \
+                   $(GZIP_DIR)/inflate.c  \
+                   $(GZIP_DIR)/inflate.h  \
+                   $(GZIP_DIR)/inftrees.c \
+                   $(GZIP_DIR)/inftrees.h \
+                   $(GZIP_DIR)/zlib.h     \
+                   $(GZIP_DIR)/zutil.c    \
+                   $(GZIP_DIR)/zutil.h
+endif
 
 # gzip driver object(s)
 #
diff --git a/src/pcf/pcfdrivr.c b/src/pcf/pcfdrivr.c
index bfa6eac..f1dba02 100644
--- a/src/pcf/pcfdrivr.c
+++ b/src/pcf/pcfdrivr.c
@@ -75,36 +75,36 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  pcf_cmap_init( FT_CMap     pcfcmap,   /* PCF_CMap */
+  pcf_cmap_init( FT_CMap     cmap,       /* PCF_CMap */
                  FT_Pointer  init_data )
   {
-    PCF_CMap  cmap = (PCF_CMap)pcfcmap;
-    PCF_Face  face = (PCF_Face)FT_CMAP_FACE( pcfcmap );
+    PCF_CMap  pcfcmap = (PCF_CMap)cmap;
+    PCF_Face  face    = (PCF_Face)FT_CMAP_FACE( cmap );
 
     FT_UNUSED( init_data );
 
 
-    cmap->enc = &face->enc;
+    pcfcmap->enc = &face->enc;
 
     return FT_Err_Ok;
   }
 
 
   FT_CALLBACK_DEF( void )
-  pcf_cmap_done( FT_CMap  pcfcmap )         /* PCF_CMap */
+  pcf_cmap_done( FT_CMap  cmap )         /* PCF_CMap */
   {
-    PCF_CMap  cmap = (PCF_CMap)pcfcmap;
+    PCF_CMap  pcfcmap = (PCF_CMap)cmap;
 
 
-    cmap->enc = NULL;
+    pcfcmap->enc = NULL;
   }
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  pcf_cmap_char_index( FT_CMap    pcfcmap,  /* PCF_CMap */
+  pcf_cmap_char_index( FT_CMap    cmap,      /* PCF_CMap */
                        FT_UInt32  charcode )
   {
-    PCF_Enc  enc = ( (PCF_CMap)pcfcmap )->enc;
+    PCF_Enc  enc = ( (PCF_CMap)cmap )->enc;
 
     FT_UInt32  i = ( charcode >> 8   ) - enc->firstRow;
     FT_UInt32  j = ( charcode & 0xFF ) - enc->firstCol;
@@ -121,10 +121,10 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  pcf_cmap_char_next( FT_CMap    pcfcmap,   /* PCF_CMap */
+  pcf_cmap_char_next( FT_CMap     cmap,       /* PCF_CMap */
                       FT_UInt32  *acharcode )
   {
-    PCF_Enc    enc = ( (PCF_CMap)pcfcmap )->enc;
+    PCF_Enc    enc = ( (PCF_CMap)cmap )->enc;
     FT_UInt32  charcode = *acharcode + 1;
 
     FT_UInt32  i = ( charcode >> 8   ) - enc->firstRow;
@@ -170,9 +170,9 @@
 
 
   FT_CALLBACK_DEF( void )
-  PCF_Face_Done( FT_Face  pcfface )         /* PCF_Face */
+  PCF_Face_Done( FT_Face  face )    /* PCF_Face */
   {
-    PCF_Face   face = (PCF_Face)pcfface;
+    PCF_Face   pcfface = (PCF_Face)face;
     FT_Memory  memory;
 
 
@@ -181,18 +181,18 @@
 
     memory = FT_FACE_MEMORY( face );
 
-    FT_FREE( face->metrics );
-    FT_FREE( face->enc.offset );
+    FT_FREE( pcfface->metrics );
+    FT_FREE( pcfface->enc.offset );
 
     /* free properties */
-    if ( face->properties )
+    if ( pcfface->properties )
     {
       FT_Int  i;
 
 
-      for ( i = 0; i < face->nprops; i++ )
+      for ( i = 0; i < pcfface->nprops; i++ )
       {
-        PCF_Property  prop = &face->properties[i];
+        PCF_Property  prop = &pcfface->properties[i];
 
 
         if ( prop )
@@ -203,33 +203,33 @@
         }
       }
 
-      FT_FREE( face->properties );
+      FT_FREE( pcfface->properties );
     }
 
-    FT_FREE( face->toc.tables );
-    FT_FREE( pcfface->family_name );
-    FT_FREE( pcfface->style_name );
-    FT_FREE( pcfface->available_sizes );
-    FT_FREE( face->charset_encoding );
-    FT_FREE( face->charset_registry );
+    FT_FREE( pcfface->toc.tables );
+    FT_FREE( face->family_name );
+    FT_FREE( face->style_name );
+    FT_FREE( face->available_sizes );
+    FT_FREE( pcfface->charset_encoding );
+    FT_FREE( pcfface->charset_registry );
 
     /* close compressed stream if any */
-    if ( pcfface->stream == &face->comp_stream )
+    if ( face->stream == &pcfface->comp_stream )
     {
-      FT_Stream_Close( &face->comp_stream );
-      pcfface->stream = face->comp_source;
+      FT_Stream_Close( &pcfface->comp_stream );
+      face->stream = pcfface->comp_source;
     }
   }
 
 
   FT_CALLBACK_DEF( FT_Error )
   PCF_Face_Init( FT_Stream      stream,
-                 FT_Face        pcfface,        /* PCF_Face */
+                 FT_Face        face,       /* PCF_Face */
                  FT_Int         face_index,
                  FT_Int         num_params,
                  FT_Parameter*  params )
   {
-    PCF_Face  face  = (PCF_Face)pcfface;
+    PCF_Face  pcfface = (PCF_Face)face;
     FT_Error  error;
 
     FT_UNUSED( num_params );
@@ -238,10 +238,10 @@
 
     FT_TRACE2(( "PCF driver\n" ));
 
-    error = pcf_load_font( stream, face, face_index );
+    error = pcf_load_font( stream, pcfface, face_index );
     if ( error )
     {
-      PCF_Face_Done( pcfface );
+      PCF_Face_Done( face );
 
 #if defined( FT_CONFIG_OPTION_USE_ZLIB )  || \
     defined( FT_CONFIG_OPTION_USE_LZW )   || \
@@ -254,7 +254,7 @@
 
         /* this didn't work, try gzip support! */
         FT_TRACE2(( "  ... try gzip stream\n" ));
-        error2 = FT_Stream_OpenGzip( &face->comp_stream, stream );
+        error2 = FT_Stream_OpenGzip( &pcfface->comp_stream, stream );
         if ( FT_ERR_EQ( error2, Unimplemented_Feature ) )
           goto Fail;
 
@@ -270,7 +270,7 @@
 
         /* this didn't work, try LZW support! */
         FT_TRACE2(( "  ... try LZW stream\n" ));
-        error3 = FT_Stream_OpenLZW( &face->comp_stream, stream );
+        error3 = FT_Stream_OpenLZW( &pcfface->comp_stream, stream );
         if ( FT_ERR_EQ( error3, Unimplemented_Feature ) )
           goto Fail;
 
@@ -286,7 +286,7 @@
 
         /* this didn't work, try Bzip2 support! */
         FT_TRACE2(( "  ... try Bzip2 stream\n" ));
-        error4 = FT_Stream_OpenBzip2( &face->comp_stream, stream );
+        error4 = FT_Stream_OpenBzip2( &pcfface->comp_stream, stream );
         if ( FT_ERR_EQ( error4, Unimplemented_Feature ) )
           goto Fail;
 
@@ -297,12 +297,12 @@
       if ( error )
         goto Fail;
 
-      face->comp_source = stream;
-      pcfface->stream   = &face->comp_stream;
+      pcfface->comp_source = stream;
+      face->stream         = &pcfface->comp_stream;
 
-      stream = pcfface->stream;
+      stream = face->stream;
 
-      error = pcf_load_font( stream, face, face_index );
+      error = pcf_load_font( stream, pcfface, face_index );
       if ( error )
         goto Fail;
 
@@ -326,14 +326,14 @@
     else if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 )
     {
       FT_ERROR(( "PCF_Face_Init: invalid face index\n" ));
-      PCF_Face_Done( pcfface );
+      PCF_Face_Done( face );
       return FT_THROW( Invalid_Argument );
     }
 
     /* set up charmap */
     {
-      FT_String  *charset_registry = face->charset_registry;
-      FT_String  *charset_encoding = face->charset_encoding;
+      FT_String  *charset_registry = pcfface->charset_registry;
+      FT_String  *charset_encoding = pcfface->charset_encoding;
       FT_Bool     unicode_charmap  = 0;
 
 
@@ -349,13 +349,13 @@
              ( s[2] == 'o' || s[2] == 'O' ) )
         {
           s += 3;
-          if ( !ft_strcmp( s, "10646" )                      ||
-               ( !ft_strcmp( s, "8859" ) &&
-                 !ft_strcmp( face->charset_encoding, "1" ) ) )
+          if ( !ft_strcmp( s, "10646" )                         ||
+               ( !ft_strcmp( s, "8859" )                      &&
+                 !ft_strcmp( pcfface->charset_encoding, "1" ) ) )
             unicode_charmap = 1;
           /* another name for ASCII */
-          else if ( !ft_strcmp( s, "646.1991" )                 &&
-                    !ft_strcmp( face->charset_encoding, "IRV" ) )
+          else if ( !ft_strcmp( s, "646.1991" )                    &&
+                    !ft_strcmp( pcfface->charset_encoding, "IRV" ) )
             unicode_charmap = 1;
         }
       }
@@ -364,7 +364,7 @@
         FT_CharMapRec  charmap;
 
 
-        charmap.face        = FT_FACE( face );
+        charmap.face        = face;
         charmap.encoding    = FT_ENCODING_NONE;
         /* initial platform/encoding should indicate unset status? */
         charmap.platform_id = TT_PLATFORM_APPLE_UNICODE;
@@ -386,7 +386,7 @@
 
   Fail:
     FT_TRACE2(( "  not a PCF file\n" ));
-    PCF_Face_Done( pcfface );
+    PCF_Face_Done( face );
     error = FT_THROW( Unknown_File_Format );  /* error */
     goto Exit;
   }
@@ -569,15 +569,16 @@
    *
    */
 
-  static FT_Error
-  pcf_get_bdf_property( PCF_Face          face,
+  FT_CALLBACK_DEF( FT_Error )
+  pcf_get_bdf_property( FT_Face           face,       /* PCF_Face */
                         const char*       prop_name,
                         BDF_PropertyRec  *aproperty )
   {
+    PCF_Face      pcfface = (PCF_Face)face;
     PCF_Property  prop;
 
 
-    prop = pcf_find_property( face, prop_name );
+    prop = pcf_find_property( pcfface, prop_name );
     if ( prop )
     {
       if ( prop->isString )
@@ -611,13 +612,16 @@
   }
 
 
-  static FT_Error
-  pcf_get_charset_id( PCF_Face      face,
+  FT_CALLBACK_DEF( FT_Error )
+  pcf_get_charset_id( FT_Face       face,               /* PCF_Face */
                       const char*  *acharset_encoding,
                       const char*  *acharset_registry )
   {
-    *acharset_encoding = face->charset_encoding;
-    *acharset_registry = face->charset_registry;
+    PCF_Face  pcfface = (PCF_Face)face;
+
+
+    *acharset_encoding = pcfface->charset_encoding;
+    *acharset_registry = pcfface->charset_registry;
 
     return FT_Err_Ok;
   }
@@ -634,7 +638,7 @@
    * PROPERTY SERVICE
    *
    */
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   pcf_property_set( FT_Module    module,         /* PCF_Driver */
                     const char*  property_name,
                     const void*  value,
@@ -695,10 +699,10 @@
   }
 
 
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   pcf_property_get( FT_Module    module,         /* PCF_Driver */
                     const char*  property_name,
-                    const void*  value )
+                    void*        value )
   {
 #ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
 
diff --git a/src/pfr/pfrcmap.c b/src/pfr/pfrcmap.c
index 312a9ff..08fe41d 100644
--- a/src/pfr/pfrcmap.c
+++ b/src/pfr/pfrcmap.c
@@ -24,17 +24,18 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  pfr_cmap_init( PFR_CMap    cmap,
+  pfr_cmap_init( FT_CMap     cmap,     /* PFR_CMap */
                  FT_Pointer  pointer )
   {
-    FT_Error  error = FT_Err_Ok;
-    PFR_Face  face  = (PFR_Face)FT_CMAP_FACE( cmap );
+    PFR_CMap  pfrcmap = (PFR_CMap)cmap;
+    FT_Error  error   = FT_Err_Ok;
+    PFR_Face  face    = (PFR_Face)FT_CMAP_FACE( cmap );
 
     FT_UNUSED( pointer );
 
 
-    cmap->num_chars = face->phy_font.num_chars;
-    cmap->chars     = face->phy_font.chars;
+    pfrcmap->num_chars = face->phy_font.num_chars;
+    pfrcmap->chars     = face->phy_font.chars;
 
     /* just for safety, check that the character entries are correctly */
     /* sorted in increasing character code order                       */
@@ -42,9 +43,9 @@
       FT_UInt  n;
 
 
-      for ( n = 1; n < cmap->num_chars; n++ )
+      for ( n = 1; n < pfrcmap->num_chars; n++ )
       {
-        if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code )
+        if ( pfrcmap->chars[n - 1].char_code >= pfrcmap->chars[n].char_code )
         {
           error = FT_THROW( Invalid_Table );
           goto Exit;
@@ -58,26 +59,30 @@
 
 
   FT_CALLBACK_DEF( void )
-  pfr_cmap_done( PFR_CMap  cmap )
+  pfr_cmap_done( FT_CMap  cmap )    /* PFR_CMap */
   {
-    cmap->chars     = NULL;
-    cmap->num_chars = 0;
+    PFR_CMap  pfrcmap = (PFR_CMap)cmap;
+
+
+    pfrcmap->chars     = NULL;
+    pfrcmap->num_chars = 0;
   }
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  pfr_cmap_char_index( PFR_CMap   cmap,
+  pfr_cmap_char_index( FT_CMap    cmap,       /* PFR_CMap */
                        FT_UInt32  char_code )
   {
-    FT_UInt   min = 0;
-    FT_UInt   max = cmap->num_chars;
-    FT_UInt   mid = min + ( max - min ) / 2;
+    PFR_CMap  pfrcmap = (PFR_CMap)cmap;
+    FT_UInt   min     = 0;
+    FT_UInt   max     = pfrcmap->num_chars;
+    FT_UInt   mid     = min + ( max - min ) / 2;
     PFR_Char  gchar;
 
 
     while ( min < max )
     {
-      gchar = cmap->chars + mid;
+      gchar = pfrcmap->chars + mid;
 
       if ( gchar->char_code == char_code )
         return mid + 1;
@@ -96,10 +101,11 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  pfr_cmap_char_next( PFR_CMap    cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  pfr_cmap_char_next( FT_CMap     cmap,        /* PFR_CMap */
                       FT_UInt32  *pchar_code )
   {
+    PFR_CMap   pfrcmap   = (PFR_CMap)cmap;
     FT_UInt    result    = 0;
     FT_UInt32  char_code = *pchar_code + 1;
 
@@ -107,14 +113,14 @@
   Restart:
     {
       FT_UInt   min = 0;
-      FT_UInt   max = cmap->num_chars;
+      FT_UInt   max = pfrcmap->num_chars;
       FT_UInt   mid = min + ( max - min ) / 2;
       PFR_Char  gchar;
 
 
       while ( min < max )
       {
-        gchar = cmap->chars + mid;
+        gchar = pfrcmap->chars + mid;
 
         if ( gchar->char_code == char_code )
         {
@@ -143,9 +149,9 @@
       /* we didn't find it, but we have a pair just above it */
       char_code = 0;
 
-      if ( min < cmap->num_chars )
+      if ( min < pfrcmap->num_chars )
       {
-        gchar  = cmap->chars + min;
+        gchar  = pfrcmap->chars + min;
         result = min;
         if ( result != 0 )
         {
diff --git a/src/pfr/pfrdrivr.c b/src/pfr/pfrdrivr.c
index 78c6c68..0048f52 100644
--- a/src/pfr/pfrdrivr.c
+++ b/src/pfr/pfrdrivr.c
@@ -27,16 +27,16 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  pfr_get_kerning( FT_Face     pfrface,     /* PFR_Face */
+  pfr_get_kerning( FT_Face     face,     /* PFR_Face */
                    FT_UInt     left,
                    FT_UInt     right,
                    FT_Vector  *avector )
   {
-    PFR_Face     face = (PFR_Face)pfrface;
-    PFR_PhyFont  phys = &face->phy_font;
+    PFR_Face     pfrface = (PFR_Face)face;
+    PFR_PhyFont  phys    = &pfrface->phy_font;
 
 
-    (void)pfr_face_get_kerning( pfrface, left, right, avector );
+    (void)pfr_face_get_kerning( face, left, right, avector );
 
     /* convert from metrics to outline units when necessary */
     if ( phys->outline_resolution != phys->metrics_resolution )
@@ -62,12 +62,12 @@
    */
 
   FT_CALLBACK_DEF( FT_Error )
-  pfr_get_advance( FT_Face   pfrface,       /* PFR_Face */
+  pfr_get_advance( FT_Face   face,       /* PFR_Face */
                    FT_UInt   gindex,
                    FT_Pos   *anadvance )
   {
-    PFR_Face  face  = (PFR_Face)pfrface;
-    FT_Error  error = FT_ERR( Invalid_Argument );
+    PFR_Face  pfrface = (PFR_Face)face;
+    FT_Error  error   = FT_ERR( Invalid_Argument );
 
 
     *anadvance = 0;
@@ -77,9 +77,9 @@
 
     gindex--;
 
-    if ( face )
+    if ( pfrface )
     {
-      PFR_PhyFont  phys = &face->phy_font;
+      PFR_PhyFont  phys = &pfrface->phy_font;
 
 
       if ( gindex < phys->num_chars )
@@ -95,16 +95,16 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  pfr_get_metrics( FT_Face    pfrface,      /* PFR_Face */
+  pfr_get_metrics( FT_Face    face,                 /* PFR_Face */
                    FT_UInt   *anoutline_resolution,
                    FT_UInt   *ametrics_resolution,
                    FT_Fixed  *ametrics_x_scale,
                    FT_Fixed  *ametrics_y_scale )
   {
-    PFR_Face     face = (PFR_Face)pfrface;
-    PFR_PhyFont  phys = &face->phy_font;
+    PFR_Face     pfrface = (PFR_Face)face;
+    PFR_PhyFont  phys    = &pfrface->phy_font;
     FT_Fixed     x_scale, y_scale;
-    FT_Size      size = face->root.size;
+    FT_Size      size    = pfrface->root.size;
 
 
     if ( anoutline_resolution )
diff --git a/src/pfr/pfrgload.c b/src/pfr/pfrgload.c
index 14f2ec3..48cf27e 100644
--- a/src/pfr/pfrgload.c
+++ b/src/pfr/pfrgload.c
@@ -560,8 +560,7 @@
                            FT_Byte*   limit )
   {
     FT_Error        error  = FT_Err_Ok;
-    FT_GlyphLoader  loader = glyph->loader;
-    FT_Memory       memory = loader->memory;
+    FT_Memory       memory = glyph->loader->memory;
     PFR_SubGlyph    subglyph;
     FT_UInt         flags, i, count, org_count;
     FT_Int          x_pos, y_pos;
diff --git a/src/pfr/pfrload.c b/src/pfr/pfrload.c
index de85ee6..856a594 100644
--- a/src/pfr/pfrload.c
+++ b/src/pfr/pfrload.c
@@ -449,15 +449,16 @@
 
   /* load bitmap strikes lists */
   FT_CALLBACK_DEF( FT_Error )
-  pfr_extra_item_load_bitmap_info( FT_Byte*     p,
-                                   FT_Byte*     limit,
-                                   PFR_PhyFont  phy_font )
+  pfr_extra_item_load_bitmap_info( FT_Byte*  p,
+                                   FT_Byte*  limit,
+                                   void*     phy_font_ )
   {
-    FT_Memory   memory = phy_font->memory;
-    PFR_Strike  strike;
-    FT_UInt     flags0;
-    FT_UInt     n, count, size1;
-    FT_Error    error = FT_Err_Ok;
+    PFR_PhyFont  phy_font = (PFR_PhyFont)phy_font_;
+    FT_Memory    memory   = phy_font->memory;
+    PFR_Strike   strike;
+    FT_UInt      flags0;
+    FT_UInt      n, count, size1;
+    FT_Error     error    = FT_Err_Ok;
 
 
     PFR_CHECK( 5 );
@@ -549,13 +550,14 @@
    * family.
    */
   FT_CALLBACK_DEF( FT_Error )
-  pfr_extra_item_load_font_id( FT_Byte*     p,
-                               FT_Byte*     limit,
-                               PFR_PhyFont  phy_font )
+  pfr_extra_item_load_font_id( FT_Byte*  p,
+                               FT_Byte*  limit,
+                               void*     phy_font_ )
   {
-    FT_Error   error  = FT_Err_Ok;
-    FT_Memory  memory = phy_font->memory;
-    FT_UInt    len    = (FT_UInt)( limit - p );
+    PFR_PhyFont  phy_font = (PFR_PhyFont)phy_font_;
+    FT_Error     error    = FT_Err_Ok;
+    FT_Memory    memory   = phy_font->memory;
+    FT_UInt      len      = (FT_UInt)( limit - p );
 
 
     if ( phy_font->font_id )
@@ -575,14 +577,15 @@
 
   /* load stem snap tables */
   FT_CALLBACK_DEF( FT_Error )
-  pfr_extra_item_load_stem_snaps( FT_Byte*     p,
-                                  FT_Byte*     limit,
-                                  PFR_PhyFont  phy_font )
+  pfr_extra_item_load_stem_snaps( FT_Byte*  p,
+                                  FT_Byte*  limit,
+                                  void*     phy_font_ )
   {
-    FT_UInt    count, num_vert, num_horz;
-    FT_Int*    snaps  = NULL;
-    FT_Error   error  = FT_Err_Ok;
-    FT_Memory  memory = phy_font->memory;
+    PFR_PhyFont  phy_font = (PFR_PhyFont)phy_font_;
+    FT_UInt      count, num_vert, num_horz;
+    FT_Int*      snaps    = NULL;
+    FT_Error     error    = FT_Err_Ok;
+    FT_Memory    memory   = phy_font->memory;
 
 
     if ( phy_font->vertical.stem_snaps )
@@ -619,10 +622,11 @@
 
   /* load kerning pair data */
   FT_CALLBACK_DEF( FT_Error )
-  pfr_extra_item_load_kerning_pairs( FT_Byte*     p,
-                                     FT_Byte*     limit,
-                                     PFR_PhyFont  phy_font )
+  pfr_extra_item_load_kerning_pairs( FT_Byte*  p,
+                                     FT_Byte*  limit,
+                                     void*     phy_font_ )
   {
+    PFR_PhyFont  phy_font = (PFR_PhyFont)phy_font_;
     PFR_KernItem  item   = NULL;
     FT_Error      error  = FT_Err_Ok;
     FT_Memory     memory = phy_font->memory;
@@ -715,10 +719,10 @@
 
   static const PFR_ExtraItemRec  pfr_phy_font_extra_items[] =
   {
-    { 1, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_bitmap_info },
-    { 2, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_font_id },
-    { 3, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_stem_snaps },
-    { 4, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_kerning_pairs },
+    { 1, pfr_extra_item_load_bitmap_info },
+    { 2, pfr_extra_item_load_font_id },
+    { 3, pfr_extra_item_load_stem_snaps },
+    { 4, pfr_extra_item_load_kerning_pairs },
     { 0, NULL }
   };
 
diff --git a/src/pfr/pfrobjs.c b/src/pfr/pfrobjs.c
index 3db8f0a..8ef17c6 100644
--- a/src/pfr/pfrobjs.c
+++ b/src/pfr/pfrobjs.c
@@ -50,14 +50,14 @@
     if ( !face )
       return;
 
-    memory = pfrface->driver->root.memory;
+    memory = pfrface->memory;
 
     /* we don't want dangling pointers */
     pfrface->family_name = NULL;
     pfrface->style_name  = NULL;
 
     /* finalize the physical font record */
-    pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) );
+    pfr_phy_font_done( &face->phy_font, memory );
 
     /* no need to finalize the logical font or the header */
     FT_FREE( pfrface->available_sizes );
@@ -214,7 +214,7 @@
         FT_UInt          n, count = phy_font->num_strikes;
         FT_Bitmap_Size*  size;
         PFR_Strike       strike;
-        FT_Memory        memory = pfrface->stream->memory;
+        FT_Memory        memory = pfrface->memory;
 
 
         if ( FT_QNEW_ARRAY( pfrface->available_sizes, count ) )
diff --git a/src/psaux/afmparse.c b/src/psaux/afmparse.c
index 68f9569..db08941 100644
--- a/src/psaux/afmparse.c
+++ b/src/psaux/afmparse.c
@@ -1086,7 +1086,7 @@
 #else /* T1_CONFIG_OPTION_NO_AFM */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _afm_parse_dummy;
+  typedef int  afm_parse_dummy_;
 
 #endif /* T1_CONFIG_OPTION_NO_AFM */
 
diff --git a/src/psaux/cffdecode.c b/src/psaux/cffdecode.c
index 2cd91c9..562d17d 100644
--- a/src/psaux/cffdecode.c
+++ b/src/psaux/cffdecode.c
@@ -2153,7 +2153,7 @@
                                       decoder->locals_bias );
 
 
-            FT_TRACE4(( " callsubr (idx %d, entering level %ld)\n",
+            FT_TRACE4(( " callsubr (idx %d, entering level %td)\n",
                         idx,
                         zone - decoder->zones + 1 ));
 
@@ -2197,7 +2197,7 @@
                                       decoder->globals_bias );
 
 
-            FT_TRACE4(( " callgsubr (idx %d, entering level %ld)\n",
+            FT_TRACE4(( " callgsubr (idx %d, entering level %td)\n",
                         idx,
                         zone - decoder->zones + 1 ));
 
@@ -2236,7 +2236,7 @@
           break;
 
         case cff_op_return:
-          FT_TRACE4(( " return (leaving level %ld)\n",
+          FT_TRACE4(( " return (leaving level %td)\n",
                       decoder->zone - decoder->zones ));
 
           if ( decoder->zone <= decoder->zones )
diff --git a/src/psaux/pshints.c b/src/psaux/pshints.c
index 6f44d0a..7bd08a9 100644
--- a/src/psaux/pshints.c
+++ b/src/psaux/pshints.c
@@ -310,7 +310,7 @@
       CF2_Hint  hint = &hintmap->edge[i];
 
 
-      FT_TRACE6(( "  %3ld    %7.2f  %7.2f  %5d  %s%s%s%s\n",
+      FT_TRACE6(( "  %3zu    %7.2f  %7.2f  %5d  %s%s%s%s\n",
                   hint->index,
                   hint->csCoord / 65536.0,
                   hint->dsCoord / ( hint->scale * 1.0 ),
diff --git a/src/psaux/t1cmap.c b/src/psaux/t1cmap.c
index bf0a393..c4bcf59 100644
--- a/src/psaux/t1cmap.c
+++ b/src/psaux/t1cmap.c
@@ -50,8 +50,11 @@
 
 
   FT_CALLBACK_DEF( void )
-  t1_cmap_std_done( T1_CMapStd  cmap )
+  t1_cmap_std_done( FT_CMap  cmap_ )   /* T1_CMapStd */
   {
+    T1_CMapStd  cmap = (T1_CMapStd)cmap_;
+
+
     cmap->num_glyphs    = 0;
     cmap->glyph_names   = NULL;
     cmap->sid_to_string = NULL;
@@ -60,10 +63,11 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  t1_cmap_std_char_index( T1_CMapStd  cmap,
-                          FT_UInt32   char_code )
+  t1_cmap_std_char_index( FT_CMap    cmap,       /* T1_CMapStd */
+                          FT_UInt32  char_code )
   {
-    FT_UInt  result = 0;
+    T1_CMapStd  t1cmap = (T1_CMapStd)cmap;
+    FT_UInt     result = 0;
 
 
     if ( char_code < 256 )
@@ -73,13 +77,13 @@
 
 
       /* convert character code to Adobe SID string */
-      code       = cmap->code_to_sid[char_code];
-      glyph_name = cmap->sid_to_string( code );
+      code       = t1cmap->code_to_sid[char_code];
+      glyph_name = t1cmap->sid_to_string( code );
 
       /* look for the corresponding glyph name */
-      for ( n = 0; n < cmap->num_glyphs; n++ )
+      for ( n = 0; n < t1cmap->num_glyphs; n++ )
       {
-        const char* gname = cmap->glyph_names[n];
+        const char* gname = t1cmap->glyph_names[n];
 
 
         if ( gname && gname[0] == glyph_name[0]  &&
@@ -95,9 +99,9 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  t1_cmap_std_char_next( T1_CMapStd   cmap,
-                         FT_UInt32   *pchar_code )
+  FT_CALLBACK_DEF( FT_UInt )
+  t1_cmap_std_char_next( FT_CMap     cmap,
+                         FT_UInt32  *pchar_code )
   {
     FT_UInt    result    = 0;
     FT_UInt32  char_code = *pchar_code + 1;
@@ -120,13 +124,14 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  t1_cmap_standard_init( T1_CMapStd  cmap,
+  t1_cmap_standard_init( FT_CMap     cmap,     /* T1_CMapStd */
                          FT_Pointer  pointer )
   {
+    T1_CMapStd  t1cmap = (T1_CMapStd)cmap;
     FT_UNUSED( pointer );
 
 
-    t1_cmap_std_init( cmap, 0 );
+    t1_cmap_std_init( t1cmap, 0 );
     return 0;
   }
 
@@ -150,13 +155,14 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  t1_cmap_expert_init( T1_CMapStd  cmap,
+  t1_cmap_expert_init( FT_CMap     cmap,     /* T1_CMapStd */
                        FT_Pointer  pointer )
   {
+    T1_CMapStd  t1cmap = (T1_CMapStd)cmap;
     FT_UNUSED( pointer );
 
 
-    t1_cmap_std_init( cmap, 1 );
+    t1_cmap_std_init( t1cmap, 1 );
     return 0;
   }
 
@@ -188,20 +194,21 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  t1_cmap_custom_init( T1_CMapCustom  cmap,
-                       FT_Pointer     pointer )
+  t1_cmap_custom_init( FT_CMap     cmap,     /* T1_CMapCustom */
+                       FT_Pointer  pointer )
   {
-    T1_Face      face     = (T1_Face)FT_CMAP_FACE( cmap );
-    T1_Encoding  encoding = &face->type1.encoding;
+    T1_CMapCustom  t1cmap   = (T1_CMapCustom)cmap;
+    T1_Face        face     = (T1_Face)FT_CMAP_FACE( cmap );
+    T1_Encoding    encoding = &face->type1.encoding;
 
     FT_UNUSED( pointer );
 
 
-    cmap->first   = (FT_UInt)encoding->code_first;
-    cmap->count   = (FT_UInt)encoding->code_last - cmap->first;
-    cmap->indices = encoding->char_index;
+    t1cmap->first   = (FT_UInt)encoding->code_first;
+    t1cmap->count   = (FT_UInt)encoding->code_last - t1cmap->first;
+    t1cmap->indices = encoding->char_index;
 
-    FT_ASSERT( cmap->indices );
+    FT_ASSERT( t1cmap->indices );
     FT_ASSERT( encoding->code_first <= encoding->code_last );
 
     return 0;
@@ -209,45 +216,50 @@
 
 
   FT_CALLBACK_DEF( void )
-  t1_cmap_custom_done( T1_CMapCustom  cmap )
+  t1_cmap_custom_done( FT_CMap  cmap )   /* T1_CMapCustom */
   {
-    cmap->indices = NULL;
-    cmap->first   = 0;
-    cmap->count   = 0;
+    T1_CMapCustom  t1cmap = (T1_CMapCustom)cmap;
+
+
+    t1cmap->indices = NULL;
+    t1cmap->first   = 0;
+    t1cmap->count   = 0;
   }
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  t1_cmap_custom_char_index( T1_CMapCustom  cmap,
-                             FT_UInt32      char_code )
+  t1_cmap_custom_char_index( FT_CMap    cmap,       /* T1_CMapCustom */
+                             FT_UInt32  char_code )
   {
-    FT_UInt    result = 0;
+    T1_CMapCustom  t1cmap = (T1_CMapCustom)cmap;
+    FT_UInt        result = 0;
 
 
-    if ( ( char_code >= cmap->first )                  &&
-         ( char_code < ( cmap->first + cmap->count ) ) )
-      result = cmap->indices[char_code];
+    if ( char_code >= t1cmap->first                    &&
+         char_code < ( t1cmap->first + t1cmap->count ) )
+      result = t1cmap->indices[char_code];
 
     return result;
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  t1_cmap_custom_char_next( T1_CMapCustom  cmap,
-                            FT_UInt32     *pchar_code )
+  FT_CALLBACK_DEF( FT_UInt )
+  t1_cmap_custom_char_next( FT_CMap     cmap,        /* T1_CMapCustom */
+                            FT_UInt32  *pchar_code )
   {
-    FT_UInt    result = 0;
-    FT_UInt32  char_code = *pchar_code;
+    T1_CMapCustom  t1cmap    = (T1_CMapCustom)cmap;
+    FT_UInt        result    = 0;
+    FT_UInt32      char_code = *pchar_code;
 
 
     char_code++;
 
-    if ( char_code < cmap->first )
-      char_code = cmap->first;
+    if ( char_code < t1cmap->first )
+      char_code = t1cmap->first;
 
-    for ( ; char_code < ( cmap->first + cmap->count ); char_code++ )
+    for ( ; char_code < ( t1cmap->first + t1cmap->count ); char_code++ )
     {
-      result = cmap->indices[char_code];
+      result = t1cmap->indices[char_code];
       if ( result != 0 )
         goto Exit;
     }
@@ -287,20 +299,24 @@
   /*************************************************************************/
 
   FT_CALLBACK_DEF( const char * )
-  psaux_get_glyph_name( T1_Face  face,
+  psaux_get_glyph_name( void*    face_,
                         FT_UInt  idx )
   {
+    T1_Face  face = (T1_Face)face_;
+
+
     return face->type1.glyph_names[idx];
   }
 
 
   FT_CALLBACK_DEF( FT_Error )
-  t1_cmap_unicode_init( PS_Unicodes  unicodes,
-                        FT_Pointer   pointer )
+  t1_cmap_unicode_init( FT_CMap     cmap,     /* PS_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;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    T1_Face             face     = (T1_Face)FT_CMAP_FACE( cmap );
+    FT_Memory           memory   = FT_FACE_MEMORY( face );
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
 
     FT_UNUSED( pointer );
 
@@ -311,17 +327,18 @@
     return psnames->unicodes_init( memory,
                                    unicodes,
                                    (FT_UInt)face->type1.num_glyphs,
-                                   (PS_GetGlyphNameFunc)&psaux_get_glyph_name,
+                                   &psaux_get_glyph_name,
                                    (PS_FreeGlyphNameFunc)NULL,
                                    (FT_Pointer)face );
   }
 
 
   FT_CALLBACK_DEF( void )
-  t1_cmap_unicode_done( PS_Unicodes  unicodes )
+  t1_cmap_unicode_done( FT_CMap  cmap )   /* PS_Unicodes */
   {
-    FT_Face    face   = FT_CMAP_FACE( unicodes );
-    FT_Memory  memory = FT_FACE_MEMORY( face );
+    PS_Unicodes  unicodes = (PS_Unicodes)cmap;
+    FT_Face      face     = FT_CMAP_FACE( cmap );
+    FT_Memory    memory   = FT_FACE_MEMORY( face );
 
 
     FT_FREE( unicodes->maps );
@@ -330,23 +347,25 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  t1_cmap_unicode_char_index( PS_Unicodes  unicodes,
-                              FT_UInt32    char_code )
+  t1_cmap_unicode_char_index( FT_CMap    cmap,       /* PS_Unicodes */
+                              FT_UInt32  char_code )
   {
-    T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    T1_Face             face     = (T1_Face)FT_CMAP_FACE( cmap );
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
 
 
     return psnames->unicodes_char_index( unicodes, char_code );
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  t1_cmap_unicode_char_next( PS_Unicodes  unicodes,
-                             FT_UInt32   *pchar_code )
+  FT_CALLBACK_DEF( FT_UInt )
+  t1_cmap_unicode_char_next( FT_CMap     cmap,        /* PS_Unicodes */
+                             FT_UInt32  *pchar_code )
   {
-    T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    T1_Face             face     = (T1_Face)FT_CMAP_FACE( cmap );
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
 
 
     return psnames->unicodes_char_next( unicodes, pchar_code );
diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c
index bfed45b..4b6b969 100644
--- a/src/psaux/t1decode.c
+++ b/src/psaux/t1decode.c
@@ -520,7 +520,7 @@
 #ifdef FT_DEBUG_LEVEL_TRACE
       if ( bol )
       {
-        FT_TRACE5(( " (%ld)", decoder->top - decoder->stack ));
+        FT_TRACE5(( " (%td)", decoder->top - decoder->stack ));
         bol = FALSE;
       }
 #endif
@@ -1165,7 +1165,7 @@
           if ( top - decoder->stack != num_args )
             FT_TRACE0(( "t1_decoder_parse_charstrings:"
                         " too much operands on the stack"
-                        " (seen %ld, expected %d)\n",
+                        " (seen %td, expected %d)\n",
                         top - decoder->stack, num_args ));
           break;
         }
diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c
index a7f3212..4f622e1 100644
--- a/src/pshinter/pshalgo.c
+++ b/src/pshinter/pshalgo.c
@@ -516,7 +516,7 @@
             if ( !psh_hint_is_fitted( parent ) )
               psh_hint_align( parent, globals, dimension, glyph );
 
-            /* keep original relation between hints, this is, use the */
+            /* keep original relation between hints, that is, use the */
             /* scaled distance between the centers of the hints to    */
             /* compute the new position                               */
             par_org_center = parent->org_pos + ( parent->org_len >> 1 );
diff --git a/src/pshinter/pshmod.c b/src/pshinter/pshmod.c
index a12e485..974a99e 100644
--- a/src/pshinter/pshmod.c
+++ b/src/pshinter/pshmod.c
@@ -37,8 +37,11 @@
 
   /* finalize module */
   FT_CALLBACK_DEF( void )
-  ps_hinter_done( PS_Hinter_Module  module )
+  ps_hinter_done( FT_Module  module_ )    /* PS_Hinter_Module */
   {
+    PS_Hinter_Module  module = (PS_Hinter_Module)module_;
+
+
     module->t1_funcs.hints = NULL;
     module->t2_funcs.hints = NULL;
 
@@ -48,8 +51,10 @@
 
   /* initialize module, create hints recorder and the interface */
   FT_CALLBACK_DEF( FT_Error )
-  ps_hinter_init( PS_Hinter_Module  module )
+  ps_hinter_init( FT_Module  module_ )    /* PS_Hinter_Module */
   {
+    PS_Hinter_Module  module = (PS_Hinter_Module)module_;
+
     FT_Memory  memory = module->root.memory;
     void*      ph     = &module->ps_hints;
 
diff --git a/src/pshinter/pshrec.c b/src/pshinter/pshrec.c
index 58c8cf1..680e6d0 100644
--- a/src/pshinter/pshrec.c
+++ b/src/pshinter/pshrec.c
@@ -851,10 +851,11 @@
 
   /* add one Type1 counter stem to the current hints table */
   static void
-  ps_hints_t1stem3( PS_Hints   hints,
+  ps_hints_t1stem3( T1_Hints   hints_,    /* PS_Hints */
                     FT_UInt    dimension,
                     FT_Fixed*  stems )
   {
+    PS_Hints  hints = (PS_Hints)hints_;
     FT_Error  error = FT_Err_Ok;
 
 
@@ -914,9 +915,10 @@
 
   /* reset hints (only with Type 1 hints) */
   static void
-  ps_hints_t1reset( PS_Hints  hints,
+  ps_hints_t1reset( T1_Hints  hints_,     /* PS_Hints */
                     FT_UInt   end_point )
   {
+    PS_Hints  hints = (PS_Hints)hints_;
     FT_Error  error = FT_Err_Ok;
 
 
@@ -953,11 +955,12 @@
 
   /* Type2 "hintmask" operator, add a new hintmask to each direction */
   static void
-  ps_hints_t2mask( PS_Hints        hints,
+  ps_hints_t2mask( T2_Hints        hints_,    /* PS_Hints */
                    FT_UInt         end_point,
                    FT_UInt         bit_count,
                    const FT_Byte*  bytes )
   {
+    PS_Hints  hints = (PS_Hints)hints_;
     FT_Error  error;
 
 
@@ -999,10 +1002,11 @@
 
 
   static void
-  ps_hints_t2counter( PS_Hints        hints,
+  ps_hints_t2counter( T2_Hints        hints_,    /* PS_Hints */
                       FT_UInt         bit_count,
                       const FT_Byte*  bytes )
   {
+    PS_Hints  hints = (PS_Hints)hints_;
     FT_Error  error;
 
 
@@ -1087,6 +1091,13 @@
     ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_1 );
   }
 
+  static FT_Error
+  t1_hints_close( T1_Hints  hints,
+                  FT_UInt   end_point )
+  {
+    return ps_hints_close( (PS_Hints)hints, end_point );
+  }
+
   static void
   t1_hints_stem( T1_Hints   hints,
                  FT_UInt    dimension,
@@ -1102,17 +1113,27 @@
   }
 
 
+  static FT_Error
+  t1_hints_apply( T1_Hints        hints,
+                  FT_Outline*     outline,
+                  PSH_Globals     globals,
+                  FT_Render_Mode  hint_mode )
+  {
+    return ps_hints_apply( (PS_Hints)hints, outline, globals, hint_mode );
+  }
+
+
   FT_LOCAL_DEF( void )
   t1_hints_funcs_init( T1_Hints_FuncsRec*  funcs )
   {
     FT_ZERO( funcs );
 
     funcs->open  = (T1_Hints_OpenFunc)    t1_hints_open;
-    funcs->close = (T1_Hints_CloseFunc)   ps_hints_close;
+    funcs->close = (T1_Hints_CloseFunc)   t1_hints_close;
     funcs->stem  = (T1_Hints_SetStemFunc) t1_hints_stem;
     funcs->stem3 = (T1_Hints_SetStem3Func)ps_hints_t1stem3;
     funcs->reset = (T1_Hints_ResetFunc)   ps_hints_t1reset;
-    funcs->apply = (T1_Hints_ApplyFunc)   ps_hints_apply;
+    funcs->apply = (T1_Hints_ApplyFunc)   t1_hints_apply;
   }
 
 
@@ -1131,6 +1152,14 @@
   }
 
 
+  static FT_Error
+  t2_hints_close( T2_Hints  hints,
+                  FT_UInt   end_point )
+  {
+    return ps_hints_close( (PS_Hints)hints, end_point );
+  }
+
+
   static void
   t2_hints_stems( T2_Hints   hints,
                   FT_UInt    dimension,
@@ -1168,17 +1197,27 @@
   }
 
 
+  static FT_Error
+  t2_hints_apply( T2_Hints        hints,
+                  FT_Outline*     outline,
+                  PSH_Globals     globals,
+                  FT_Render_Mode  hint_mode )
+  {
+    return ps_hints_apply( (PS_Hints)hints, outline, globals, hint_mode );
+  }
+
+
   FT_LOCAL_DEF( void )
   t2_hints_funcs_init( T2_Hints_FuncsRec*  funcs )
   {
     FT_ZERO( funcs );
 
-    funcs->open    = (T2_Hints_OpenFunc)   t2_hints_open;
-    funcs->close   = (T2_Hints_CloseFunc)  ps_hints_close;
-    funcs->stems   = (T2_Hints_StemsFunc)  t2_hints_stems;
-    funcs->hintmask= (T2_Hints_MaskFunc)   ps_hints_t2mask;
-    funcs->counter = (T2_Hints_CounterFunc)ps_hints_t2counter;
-    funcs->apply   = (T2_Hints_ApplyFunc)  ps_hints_apply;
+    funcs->open     = (T2_Hints_OpenFunc)   t2_hints_open;
+    funcs->close    = (T2_Hints_CloseFunc)  t2_hints_close;
+    funcs->stems    = (T2_Hints_StemsFunc)  t2_hints_stems;
+    funcs->hintmask = (T2_Hints_MaskFunc)   ps_hints_t2mask;
+    funcs->counter  = (T2_Hints_CounterFunc)ps_hints_t2counter;
+    funcs->apply    = (T2_Hints_ApplyFunc)  t2_hints_apply;
   }
 
 
diff --git a/src/psnames/psmodule.c b/src/psnames/psmodule.c
index db454e5..8203a04 100644
--- a/src/psnames/psmodule.c
+++ b/src/psnames/psmodule.c
@@ -57,7 +57,7 @@
   /* the name, as in `A.swash' or `e.final'; in this case, the           */
   /* VARIANT_BIT is set in the return value.                             */
   /*                                                                     */
-  static FT_UInt32
+  FT_CALLBACK_DEF( FT_UInt32 )
   ps_unicode_value( const char*  glyph_name )
   {
     /* If the name begins with `uni', then the glyph name may be a */
@@ -309,7 +309,7 @@
 
 
   /* Build a table that maps Unicode values to glyph indices. */
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   ps_unicodes_init( FT_Memory             memory,
                     PS_Unicodes           table,
                     FT_UInt               num_glyphs,
@@ -408,7 +408,7 @@
   }
 
 
-  static FT_UInt
+  FT_CALLBACK_DEF( FT_UInt )
   ps_unicodes_char_index( PS_Unicodes  table,
                           FT_UInt32    unicode )
   {
@@ -453,7 +453,7 @@
   }
 
 
-  static FT_UInt32
+  FT_CALLBACK_DEF( FT_UInt )
   ps_unicodes_char_next( PS_Unicodes  table,
                          FT_UInt32   *unicode )
   {
@@ -518,7 +518,7 @@
 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
 
 
-  static const char*
+  FT_CALLBACK_DEF( const char* )
   ps_get_macintosh_name( FT_UInt  name_index )
   {
     if ( name_index >= FT_NUM_MAC_NAMES )
@@ -528,7 +528,7 @@
   }
 
 
-  static const char*
+  FT_CALLBACK_DEF( const char* )
   ps_get_standard_strings( FT_UInt  sid )
   {
     if ( sid >= FT_NUM_SID_NAMES )
@@ -543,13 +543,13 @@
   FT_DEFINE_SERVICE_PSCMAPSREC(
     pscmaps_interface,
 
-    (PS_Unicode_ValueFunc)     ps_unicode_value,        /* unicode_value         */
-    (PS_Unicodes_InitFunc)     ps_unicodes_init,        /* unicodes_init         */
-    (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index,  /* unicodes_char_index   */
-    (PS_Unicodes_CharNextFunc) ps_unicodes_char_next,   /* unicodes_char_next    */
+    ps_unicode_value,         /* PS_Unicode_ValueFunc      unicode_value         */
+    ps_unicodes_init,         /* PS_Unicodes_InitFunc      unicodes_init         */
+    ps_unicodes_char_index,   /* PS_Unicodes_CharIndexFunc unicodes_char_index   */
+    ps_unicodes_char_next,    /* PS_Unicodes_CharNextFunc  unicodes_char_next    */
 
-    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,   /* macintosh_name        */
-    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings     */
+    ps_get_macintosh_name,    /* PS_Macintosh_NameFunc     macintosh_name        */
+    ps_get_standard_strings,  /* PS_Adobe_Std_StringsFunc  adobe_std_strings     */
 
     t1_standard_encoding,                               /* adobe_std_encoding    */
     t1_expert_encoding                                  /* adobe_expert_encoding */
@@ -560,13 +560,13 @@
   FT_DEFINE_SERVICE_PSCMAPSREC(
     pscmaps_interface,
 
-    NULL,                                               /* unicode_value         */
-    NULL,                                               /* unicodes_init         */
-    NULL,                                               /* unicodes_char_index   */
-    NULL,                                               /* unicodes_char_next    */
+    NULL,                     /* PS_Unicode_ValueFunc      unicode_value         */
+    NULL,                     /* PS_Unicodes_InitFunc      unicodes_init         */
+    NULL,                     /* PS_Unicodes_CharIndexFunc unicodes_char_index   */
+    NULL,                     /* PS_Unicodes_CharNextFunc  unicodes_char_next    */
 
-    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,   /* macintosh_name        */
-    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings     */
+    ps_get_macintosh_name,    /* PS_Macintosh_NameFunc     macintosh_name        */
+    ps_get_standard_strings,  /* PS_Adobe_Std_StringsFunc  adobe_std_strings     */
 
     t1_standard_encoding,                               /* adobe_std_encoding    */
     t1_expert_encoding                                  /* adobe_expert_encoding */
@@ -612,9 +612,9 @@
     PUT_PS_NAMES_SERVICE(
       (void*)&pscmaps_interface ),   /* module specific interface */
 
-    (FT_Module_Constructor)NULL,                                       /* module_init   */
-    (FT_Module_Destructor) NULL,                                       /* module_done   */
-    (FT_Module_Requester)  PUT_PS_NAMES_SERVICE( psnames_get_service ) /* get_interface */
+    NULL,                                        /* FT_Module_Constructor module_init   */
+    NULL,                                        /* FT_Module_Destructor  module_done   */
+    PUT_PS_NAMES_SERVICE( psnames_get_service )  /* FT_Module_Requester   get_interface */
   )
 
 
diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c
index 67cbfd5..192ca07 100644
--- a/src/raster/ftraster.c
+++ b/src/raster/ftraster.c
@@ -1742,9 +1742,9 @@
    *   SUCCESS on success, FAILURE on error.
    */
   static Bool
-  Decompose_Curve( RAS_ARGS UShort  first,
-                            UShort  last,
-                            Int     flipped )
+  Decompose_Curve( RAS_ARGS Int  first,
+                            Int  last,
+                            Int  flipped )
   {
     FT_Vector   v_last;
     FT_Vector   v_control;
@@ -1969,8 +1969,8 @@
   static Bool
   Convert_Glyph( RAS_ARGS Int  flipped )
   {
-    Int   i;
-    UInt  start;
+    Int  i;
+    Int  first, last;
 
 
     ras.fProfile = NULL;
@@ -1985,8 +1985,7 @@
     ras.cProfile->offset = ras.top;
     ras.num_Profs        = 0;
 
-    start = 0;
-
+    last = -1;
     for ( i = 0; i < ras.outline.n_contours; i++ )
     {
       PProfile  lastProfile;
@@ -1996,12 +1995,11 @@
       ras.state    = Unknown_State;
       ras.gProfile = NULL;
 
-      if ( Decompose_Curve( RAS_VARS (UShort)start,
-                                     (UShort)ras.outline.contours[i],
-                                     flipped ) )
-        return FAILURE;
+      first = last + 1;
+      last  = ras.outline.contours[i];
 
-      start = (UShort)ras.outline.contours[i] + 1;
+      if ( Decompose_Curve( RAS_VARS first, last, flipped ) )
+        return FAILURE;
 
       /* we must now check whether the extreme arcs join or not */
       if ( FRAC( ras.lastY ) == 0 &&
@@ -3167,9 +3165,12 @@
 
 
   static int
-  ft_black_new( FT_Memory       memory,
-                black_PRaster  *araster )
+  ft_black_new( void*       memory_,    /* FT_Memory     */
+                FT_Raster  *araster_ )  /* black_PRaster */
   {
+    FT_Memory       memory = (FT_Memory)memory_;
+    black_PRaster  *araster = (black_PRaster*)araster_;
+
     FT_Error       error;
     black_PRaster  raster = NULL;
 
@@ -3184,9 +3185,10 @@
 
 
   static void
-  ft_black_done( black_PRaster  raster )
+  ft_black_done( FT_Raster  raster_ )   /* black_PRaster */
   {
-    FT_Memory  memory = (FT_Memory)raster->memory;
+    black_PRaster  raster = (black_PRaster)raster_;
+    FT_Memory      memory = (FT_Memory)raster->memory;
 
 
     FT_FREE( raster );
@@ -3281,11 +3283,11 @@
 
     FT_GLYPH_FORMAT_OUTLINE,
 
-    (FT_Raster_New_Func)     ft_black_new,       /* raster_new      */
-    (FT_Raster_Reset_Func)   ft_black_reset,     /* raster_reset    */
-    (FT_Raster_Set_Mode_Func)ft_black_set_mode,  /* raster_set_mode */
-    (FT_Raster_Render_Func)  ft_black_render,    /* raster_render   */
-    (FT_Raster_Done_Func)    ft_black_done       /* raster_done     */
+    ft_black_new,       /* FT_Raster_New_Func      raster_new      */
+    ft_black_reset,     /* FT_Raster_Reset_Func    raster_reset    */
+    ft_black_set_mode,  /* FT_Raster_Set_Mode_Func raster_set_mode */
+    ft_black_render,    /* FT_Raster_Render_Func   raster_render   */
+    ft_black_done       /* FT_Raster_Done_Func     raster_done     */
   )
 
 
diff --git a/src/raster/ftrend1.c b/src/raster/ftrend1.c
index 0b5d867..6d442b1 100644
--- a/src/raster/ftrend1.c
+++ b/src/raster/ftrend1.c
@@ -27,8 +27,11 @@
 
   /* initialize renderer -- init its raster */
   static FT_Error
-  ft_raster1_init( FT_Renderer  render )
+  ft_raster1_init( FT_Module  module )   /* FT_Renderer */
   {
+    FT_Renderer  render = (FT_Renderer)module;
+
+
     render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
 
     return FT_Err_Ok;
@@ -188,18 +191,18 @@
 
       NULL,    /* module specific interface */
 
-      (FT_Module_Constructor)ft_raster1_init,  /* module_init   */
-      (FT_Module_Destructor) NULL,             /* module_done   */
-      (FT_Module_Requester)  NULL,             /* get_interface */
+      ft_raster1_init,  /* FT_Module_Constructor module_init   */
+      NULL,             /* FT_Module_Destructor  module_done   */
+      NULL,             /* FT_Module_Requester   get_interface */
 
     FT_GLYPH_FORMAT_OUTLINE,
 
-    (FT_Renderer_RenderFunc)   ft_raster1_render,     /* render_glyph    */
-    (FT_Renderer_TransformFunc)ft_raster1_transform,  /* transform_glyph */
-    (FT_Renderer_GetCBoxFunc)  ft_raster1_get_cbox,   /* get_glyph_cbox  */
-    (FT_Renderer_SetModeFunc)  ft_raster1_set_mode,   /* set_mode        */
+    ft_raster1_render,     /* FT_Renderer_RenderFunc    render_glyph    */
+    ft_raster1_transform,  /* FT_Renderer_TransformFunc transform_glyph */
+    ft_raster1_get_cbox,   /* FT_Renderer_GetCBoxFunc   get_glyph_cbox  */
+    ft_raster1_set_mode,   /* FT_Renderer_SetModeFunc   set_mode        */
 
-    (FT_Raster_Funcs*)&ft_standard_raster             /* raster_class    */
+    &ft_standard_raster    /* FT_Raster_Funcs*          raster_class    */
   )
 
 
diff --git a/src/sdf/ftbsdf.c b/src/sdf/ftbsdf.c
index 901d8b7..e472738 100644
--- a/src/sdf/ftbsdf.c
+++ b/src/sdf/ftbsdf.c
@@ -1173,9 +1173,12 @@
 
   /* called when adding a new module through @FT_Add_Module */
   static FT_Error
-  bsdf_raster_new( FT_Memory      memory,
-                   BSDF_PRaster*  araster )
+  bsdf_raster_new( void*       memory_,    /* FT_Memory     */
+                   FT_Raster*  araster_ )  /* BSDF_PRaster* */
   {
+    FT_Memory      memory  = (FT_Memory)memory_;
+    BSDF_PRaster*  araster = (BSDF_PRaster*)araster_;
+
     FT_Error      error;
     BSDF_PRaster  raster = NULL;
 
diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c
index 26a6d00..bc4625d 100644
--- a/src/sdf/ftsdf.c
+++ b/src/sdf/ftsdf.c
@@ -2371,11 +2371,11 @@
      *     ```
      *
      * (6) Our task is to find a value of `t` such that the above equation
-     *     `Q(t)` becomes zero, this is, the point-to-curve vector makes
+     *     `Q(t)` becomes zero, that is, the point-to-curve vector makes
      *     90~degrees with the curve.  We solve this with the Newton-Raphson
      *     method.
      *
-     * (7) We first assume an arbitary value of factor `t`, which we then
+     * (7) We first assume an arbitrary value of factor `t`, which we then
      *     improve.
      *
      *     ```
@@ -2684,11 +2684,11 @@
      *     ```
      *
      * (6) Our task is to find a value of `t` such that the above equation
-     *     `Q(t)` becomes zero, this is, the point-to-curve vector makes
+     *     `Q(t)` becomes zero, that is, the point-to-curve vector makes
      *     90~degree with curve.  We solve this with the Newton-Raphson
      *     method.
      *
-     * (7) We first assume an arbitary value of factor `t`, which we then
+     * (7) We first assume an arbitrary value of factor `t`, which we then
      *     improve.
      *
      *     ```
@@ -2718,8 +2718,9 @@
 
     FT_Error  error = FT_Err_Ok;
 
-    FT_26D6_Vec   aA, bB, cC, dD; /* A, B, C in the above comment          */
-    FT_16D16_Vec  nearest_point;  /* point on curve nearest to `point`     */
+    FT_26D6_Vec   aA, bB, cC, dD; /* A, B, C, D in the above comment       */
+    FT_16D16_Vec  nearest_point = { 0, 0 };
+                                  /* point on curve nearest to `point`     */
     FT_16D16_Vec  direction;      /* direction of curve at `nearest_point` */
 
     FT_26D6_Vec  p0, p1, p2, p3;  /* control points of a cubic curve       */
@@ -3761,9 +3762,13 @@
    */
 
   static FT_Error
-  sdf_raster_new( FT_Memory     memory,
-                  SDF_PRaster*  araster )
+  sdf_raster_new( void*       memory_,   /* FT_Memory    */
+                  FT_Raster*  araster_ ) /* SDF_PRaster* */
   {
+    FT_Memory     memory  = (FT_Memory)memory_;
+    SDF_PRaster*  araster = (SDF_PRaster*)araster_;
+
+
     FT_Error     error;
     SDF_PRaster  raster = NULL;
 
diff --git a/src/sdf/ftsdfrend.c b/src/sdf/ftsdfrend.c
index 9ac7d6f..5610c11 100644
--- a/src/sdf/ftsdfrend.c
+++ b/src/sdf/ftsdfrend.c
@@ -197,10 +197,10 @@
 
 
   static FT_Module_Interface
-  ft_sdf_requester( FT_Renderer  render,
+  ft_sdf_requester( FT_Module    module,
                     const char*  module_interface )
   {
-    FT_UNUSED( render );
+    FT_UNUSED( module );
 
     return ft_service_list_lookup( sdf_services, module_interface );
   }
@@ -221,9 +221,9 @@
    */
 
   static FT_Error
-  ft_sdf_init( FT_Renderer  render )
+  ft_sdf_init( FT_Module  module )   /* SDF_Renderer */
   {
-    SDF_Renderer  sdf_render = SDF_RENDERER( render );
+    SDF_Renderer  sdf_render = SDF_RENDERER( module );
 
 
     sdf_render->spread    = DEFAULT_SPREAD;
@@ -236,9 +236,9 @@
 
 
   static void
-  ft_sdf_done( FT_Renderer  render )
+  ft_sdf_done( FT_Module  module )
   {
-    FT_UNUSED( render );
+    FT_UNUSED( module );
   }
 
 
@@ -300,7 +300,7 @@
 
     /* nothing to render */
     if ( !bitmap->rows || !bitmap->pitch )
-      return FT_Err_Ok;
+      goto Exit;
 
     /* the padding will simply be equal to the `spread' */
     x_pad = sdf_module->spread;
@@ -508,6 +508,10 @@
       goto Exit;
     }
 
+    /* nothing to render */
+    if ( !bitmap->rows || !bitmap->pitch )
+      goto Exit;
+
     /* Do not generate SDF if the bitmap is not owned by the       */
     /* glyph: it might be that the source buffer is already freed. */
     if ( !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
@@ -519,10 +523,6 @@
       goto Exit;
     }
 
-    /* nothing to render */
-    if ( !bitmap->rows || !bitmap->pitch )
-      return FT_Err_Ok;
-
     FT_Bitmap_New( &target );
 
     /* padding will simply be equal to `spread` */
@@ -557,15 +557,14 @@
     {
       /* the glyph is successfully converted to a SDF */
       if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
-      {
         FT_FREE( bitmap->buffer );
-        slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
-      }
 
-      slot->bitmap           = target;
-      slot->bitmap_top      += y_pad;
-      slot->bitmap_left     -= x_pad;
-      slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
+      slot->bitmap       = target;
+      slot->bitmap_top  += y_pad;
+      slot->bitmap_left -= x_pad;
+
+      if ( target.buffer )
+        slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
     }
     else if ( target.buffer )
       FT_FREE( target.buffer );
diff --git a/src/sfnt/pngshim.c b/src/sfnt/pngshim.c
index 423b07b..3371216 100644
--- a/src/sfnt/pngshim.c
+++ b/src/sfnt/pngshim.c
@@ -406,10 +406,7 @@
 
     switch ( color_type )
     {
-    default:
-      /* Shouldn't happen, but ... */
-      FALL_THROUGH;
-
+    default:  /* Shouldn't happen, but ... */
     case PNG_COLOR_TYPE_RGB_ALPHA:
       png_set_read_user_transform_fn( png, premultiply_data );
       break;
@@ -457,7 +454,7 @@
 #else /* !(TT_CONFIG_OPTION_EMBEDDED_BITMAPS && FT_CONFIG_OPTION_USE_PNG) */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _pngshim_dummy;
+  typedef int  pngshim_dummy_;
 
 #endif /* !(TT_CONFIG_OPTION_EMBEDDED_BITMAPS && FT_CONFIG_OPTION_USE_PNG) */
 
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
index 762883d..0925940 100644
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -79,41 +79,57 @@
    *
    */
 
-  static void*
-  get_sfnt_table( TT_Face      face,
+  FT_CALLBACK_DEF( FT_Error )
+  sfnt_load_table( FT_Face    face,    /* TT_Face */
+                   FT_ULong   tag,
+                   FT_Long    offset,
+                   FT_Byte*   buffer,
+                   FT_ULong*  length )
+  {
+    TT_Face  ttface = (TT_Face)face;
+
+
+    return tt_face_load_any( ttface, tag, offset, buffer, length );
+  }
+
+
+  FT_CALLBACK_DEF( void* )
+  get_sfnt_table( FT_Face      face,  /* TT_Face */
                   FT_Sfnt_Tag  tag )
   {
+    TT_Face  ttface = (TT_Face)face;
+
     void*  table;
 
 
     switch ( tag )
     {
     case FT_SFNT_HEAD:
-      table = &face->header;
+      table = &ttface->header;
       break;
 
     case FT_SFNT_HHEA:
-      table = &face->horizontal;
+      table = &ttface->horizontal;
       break;
 
     case FT_SFNT_VHEA:
-      table = face->vertical_info ? &face->vertical : NULL;
+      table = ttface->vertical_info ? &ttface->vertical : NULL;
       break;
 
     case FT_SFNT_OS2:
-      table = ( face->os2.version == 0xFFFFU ) ? NULL : &face->os2;
+      table = ( ttface->os2.version == 0xFFFFU ) ? NULL : &ttface->os2;
       break;
 
     case FT_SFNT_POST:
-      table = &face->postscript;
+      table = &ttface->postscript;
       break;
 
     case FT_SFNT_MAXP:
-      table = &face->max_profile;
+      table = &ttface->max_profile;
       break;
 
     case FT_SFNT_PCLT:
-      table = face->pclt.Version ? &face->pclt : NULL;
+      table = ttface->pclt.Version ? &ttface->pclt : NULL;
       break;
 
     default:
@@ -124,26 +140,29 @@
   }
 
 
-  static FT_Error
-  sfnt_table_info( TT_Face    face,
+  FT_CALLBACK_DEF( FT_Error )
+  sfnt_table_info( FT_Face    face,    /* TT_Face */
                    FT_UInt    idx,
                    FT_ULong  *tag,
                    FT_ULong  *offset,
                    FT_ULong  *length )
   {
+    TT_Face  ttface = (TT_Face)face;
+
+
     if ( !offset || !length )
       return FT_THROW( Invalid_Argument );
 
     if ( !tag )
-      *length = face->num_tables;
+      *length = ttface->num_tables;
     else
     {
-      if ( idx >= face->num_tables )
+      if ( idx >= ttface->num_tables )
         return FT_THROW( Table_Missing );
 
-      *tag    = face->dir_tables[idx].Tag;
-      *offset = face->dir_tables[idx].Offset;
-      *length = face->dir_tables[idx].Length;
+      *tag    = ttface->dir_tables[idx].Tag;
+      *offset = ttface->dir_tables[idx].Offset;
+      *length = ttface->dir_tables[idx].Length;
     }
 
     return FT_Err_Ok;
@@ -153,9 +172,9 @@
   FT_DEFINE_SERVICE_SFNT_TABLEREC(
     sfnt_service_sfnt_table,
 
-    (FT_SFNT_TableLoadFunc)tt_face_load_any,     /* load_table */
-    (FT_SFNT_TableGetFunc) get_sfnt_table,       /* get_table  */
-    (FT_SFNT_TableInfoFunc)sfnt_table_info       /* table_info */
+    sfnt_load_table,  /* FT_SFNT_TableLoadFunc load_table */
+    get_sfnt_table,   /* FT_SFNT_TableGetFunc  get_table  */
+    sfnt_table_info   /* FT_SFNT_TableInfoFunc table_info */
   )
 
 
@@ -166,7 +185,7 @@
    *
    */
 
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   sfnt_get_glyph_name( FT_Face     face,
                        FT_UInt     glyph_index,
                        FT_Pointer  buffer,
@@ -184,7 +203,7 @@
   }
 
 
-  static FT_UInt
+  FT_CALLBACK_DEF( FT_UInt )
   sfnt_get_name_index( FT_Face           face,
                        const FT_String*  glyph_name )
   {
@@ -221,8 +240,8 @@
   FT_DEFINE_SERVICE_GLYPHDICTREC(
     sfnt_service_glyph_dict,
 
-    (FT_GlyphDict_GetNameFunc)  sfnt_get_glyph_name,    /* get_name   */
-    (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index     /* name_index */
+    sfnt_get_glyph_name,  /* FT_GlyphDict_GetNameFunc   get_name   */
+    sfnt_get_name_index   /* FT_GlyphDict_NameIndexFunc name_index */
   )
 
 #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
@@ -523,15 +542,14 @@
           FT_TRACE0(( "get_win_string:"
                       " Character 0x%X invalid in PS name string\n",
                       ((unsigned)p[0])*256 + (unsigned)p[1] ));
-        break;
+        continue;
       }
     }
-    if ( !len )
-      *r = '\0';
+    *r = '\0';
 
     FT_FRAME_EXIT();
 
-    if ( !len )
+    if ( r != result )
       return result;
 
   get_win_string_error:
@@ -580,15 +598,14 @@
           FT_TRACE0(( "get_apple_string:"
                       " Character `%c' (0x%X) invalid in PS name string\n",
                       *p, *p ));
-        break;
+        continue;
       }
     }
-    if ( !len )
-      *r = '\0';
+    *r = '\0';
 
     FT_FRAME_EXIT();
 
-    if ( !len )
+    if ( r != result )
       return result;
 
   get_apple_string_error:
@@ -602,7 +619,7 @@
   }
 
 
-  static FT_Bool
+  FT_CALLBACK_DEF( FT_Bool )
   sfnt_get_name_id( TT_Face    face,
                     FT_UShort  id,
                     FT_Int    *win,
@@ -819,9 +836,9 @@
 
       if ( !found )
       {
-        /* as a last resort we try the family name; note that this is */
-        /* not in the Adobe TechNote, but GX fonts (which predate the */
-        /* TechNote) benefit from this behaviour                      */
+        /* according to the 'name' documentation in the OpenType   */
+        /* specification the font family name is to be used if the */
+        /* typographic family name is missing, so let's do that    */
         found = sfnt_get_name_id( face,
                                   TT_NAME_ID_FONT_FAMILY,
                                   &win,
@@ -853,6 +870,10 @@
       {
         FT_TRACE0(( "sfnt_get_var_ps_name:"
                     " No valid PS name prefix for font instances found\n" ));
+        /* XXX It probably makes sense to never let this fail */
+        /*     since an arbitrary prefix should work, too.    */
+        /*     On the other hand, it is very unlikely that    */
+        /*     we ever reach this code at all.                */
         return NULL;
       }
 
@@ -1041,47 +1062,49 @@
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
 
 
-  static const char*
-  sfnt_get_ps_name( TT_Face  face )
+  FT_CALLBACK_DEF( const char* )
+  sfnt_get_ps_name( FT_Face  face )    /* TT_Face */
   {
+    TT_Face  ttface = (TT_Face)face;
+
     FT_Int       found, win, apple;
     const char*  result = NULL;
 
 
-    if ( face->postscript_name )
-      return face->postscript_name;
+    if ( ttface->postscript_name )
+      return ttface->postscript_name;
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-    if ( face->blend                                 &&
-         ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
-           FT_IS_VARIATION( FT_FACE( face ) )      ) )
+    if ( ttface->blend                    &&
+         ( FT_IS_NAMED_INSTANCE( face ) ||
+           FT_IS_VARIATION( face )      ) )
     {
-      face->postscript_name = sfnt_get_var_ps_name( face );
-      return face->postscript_name;
+      ttface->postscript_name = sfnt_get_var_ps_name( ttface );
+      return ttface->postscript_name;
     }
 #endif
 
     /* scan the name table to see whether we have a Postscript name here, */
     /* either in Macintosh or Windows platform encodings                  */
-    found = sfnt_get_name_id( face, TT_NAME_ID_PS_NAME, &win, &apple );
+    found = sfnt_get_name_id( ttface, TT_NAME_ID_PS_NAME, &win, &apple );
     if ( !found )
       return NULL;
 
     /* prefer Windows entries over Apple */
     if ( win != -1 )
-      result = get_win_string( face->root.memory,
-                               face->name_table.stream,
-                               face->name_table.names + win,
+      result = get_win_string( FT_FACE_MEMORY( face ),
+                               ttface->name_table.stream,
+                               ttface->name_table.names + win,
                                sfnt_is_postscript,
                                1 );
     if ( !result && apple != -1 )
-      result = get_apple_string( face->root.memory,
-                                 face->name_table.stream,
-                                 face->name_table.names + apple,
+      result = get_apple_string( FT_FACE_MEMORY( face ),
+                                 ttface->name_table.stream,
+                                 ttface->name_table.names + apple,
                                  sfnt_is_postscript,
                                  1 );
 
-    face->postscript_name = result;
+    ttface->postscript_name = result;
 
     return result;
   }
@@ -1090,7 +1113,7 @@
   FT_DEFINE_SERVICE_PSFONTNAMEREC(
     sfnt_service_ps_name,
 
-    (FT_PsName_GetFunc)sfnt_get_ps_name       /* get_ps_font_name */
+    sfnt_get_ps_name  /* FT_PsName_GetFunc get_ps_font_name */
   )
 
 
@@ -1100,14 +1123,14 @@
   FT_DEFINE_SERVICE_TTCMAPSREC(
     tt_service_get_cmap_info,
 
-    (TT_CMap_Info_GetFunc)tt_get_cmap_info    /* get_cmap_info */
+    tt_get_cmap_info  /* TT_CMap_Info_GetFunc get_cmap_info */
   )
 
 
 #ifdef TT_CONFIG_OPTION_BDF
 
   static FT_Error
-  sfnt_get_charset_id( TT_Face       face,
+  sfnt_get_charset_id( FT_Face       face,
                        const char*  *acharset_encoding,
                        const char*  *acharset_registry )
   {
@@ -1145,8 +1168,8 @@
   FT_DEFINE_SERVICE_BDFRec(
     sfnt_service_bdf,
 
-    (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id,     /* get_charset_id */
-    (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop    /* get_property   */
+    sfnt_get_charset_id,   /* FT_BDF_GetCharsetIdFunc get_charset_id */
+    tt_face_find_bdf_prop  /* FT_BDF_GetPropertyFunc  get_property   */
   )
 
 
@@ -1337,9 +1360,9 @@
 
     (const void*)&sfnt_interface,  /* module specific interface */
 
-    (FT_Module_Constructor)NULL,               /* module_init   */
-    (FT_Module_Destructor) NULL,               /* module_done   */
-    (FT_Module_Requester)  sfnt_get_interface  /* get_interface */
+    NULL,               /* FT_Module_Constructor module_init   */
+    NULL,               /* FT_Module_Destructor  module_done   */
+    sfnt_get_interface  /* FT_Module_Requester   get_interface */
   )
 
 
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 312d46b..f5d66ef 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -698,6 +698,9 @@
           instance_offset += instance_size;
         }
 
+        /* named instance indices start with value 1 */
+        face->var_default_named_instance = i + 1;
+
         if ( i == num_instances )
         {
           /* no default instance in named instance table; */
@@ -1060,6 +1063,16 @@
         GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
     }
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    {
+      FT_Memory  memory = face->root.memory;
+
+
+      if ( FT_STRDUP( face->non_var_style_name, face->root.style_name ) )
+        goto Exit;
+    }
+#endif
+
     /* now set up root fields */
     {
       FT_Face  root  = &face->root;
@@ -1227,7 +1240,7 @@
 
         if ( count > 0 )
         {
-          FT_Memory        memory   = face->root.stream->memory;
+          FT_Memory        memory   = face->root.memory;
           FT_UShort        em_size  = face->header.Units_Per_EM;
           FT_Short         avgwidth = face->os2.xAvgCharWidth;
           FT_Size_Metrics  metrics;
@@ -1506,6 +1519,7 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     FT_FREE( face->var_postscript_prefix );
+    FT_FREE( face->non_var_style_name );
 #endif
 
     /* freeing glyph color palette data */
diff --git a/src/sfnt/sfwoff.c b/src/sfnt/sfwoff.c
index 9559bf3..7c0ce22 100644
--- a/src/sfnt/sfwoff.c
+++ b/src/sfnt/sfwoff.c
@@ -426,7 +426,7 @@
 #else /* !FT_CONFIG_OPTION_USE_ZLIB */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _sfwoff_dummy;
+  typedef int  sfwoff_dummy_;
 
 #endif /* !FT_CONFIG_OPTION_USE_ZLIB */
 
diff --git a/src/sfnt/sfwoff2.c b/src/sfnt/sfwoff2.c
index 7a01977..2be44a3 100644
--- a/src/sfnt/sfwoff2.c
+++ b/src/sfnt/sfwoff2.c
@@ -36,6 +36,8 @@
 #undef  FT_COMPONENT
 #define FT_COMPONENT  sfwoff2
 
+  /* An arbitrary, heuristic size limit (67MByte) for expanded WOFF2 data. */
+#define MAX_SFNT_SIZE  ( 1 << 26 )
 
 #define READ_255USHORT( var )  FT_SET_ERROR( Read255UShort( stream, &var ) )
 
@@ -2180,9 +2182,8 @@
       else
         sfnt_size = woff2.totalSfntSize;
 
-      /* Value 1<<26 = 67108864 is heuristic. */
-      if (sfnt_size >= (1 << 26))
-        sfnt_size = 1 << 26;
+      if ( sfnt_size >= MAX_SFNT_SIZE )
+        sfnt_size = MAX_SFNT_SIZE;
 
 #ifdef FT_DEBUG_LEVEL_TRACE
       if ( sfnt_size != woff2.totalSfntSize )
@@ -2257,10 +2258,15 @@
       goto Exit;
     }
 
-    if ( woff2.uncompressed_size > sfnt_size )
+    /* We must not blindly trust `uncompressed_size` since its   */
+    /* value might be corrupted.  If it is too large, reject the */
+    /* font.  In other words, we don't accept a WOFF2 font that  */
+    /* expands to something larger than MAX_SFNT_SIZE.  If ever  */
+    /* necessary, this limit can be easily adjusted.             */
+    if ( woff2.uncompressed_size > MAX_SFNT_SIZE )
     {
-      FT_ERROR(( "woff2_open_font: SFNT table lengths are too large.\n" ));
-      error = FT_THROW( Invalid_Table );
+      FT_ERROR(( "Uncompressed font too large.\n" ));
+      error = FT_THROW( Array_Too_Large );
       goto Exit;
     }
 
@@ -2378,7 +2384,7 @@
 #else /* !FT_CONFIG_OPTION_USE_BROTLI */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _sfwoff2_dummy;
+  typedef int  sfwoff2_dummy_;
 
 #endif /* !FT_CONFIG_OPTION_USE_BROTLI */
 
diff --git a/src/sfnt/ttbdf.c b/src/sfnt/ttbdf.c
index 118f475..536fa74 100644
--- a/src/sfnt/ttbdf.c
+++ b/src/sfnt/ttbdf.c
@@ -136,13 +136,14 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  tt_face_find_bdf_prop( TT_Face           face,
+  tt_face_find_bdf_prop( FT_Face           face,          /* TT_Face */
                          const char*       property_name,
                          BDF_PropertyRec  *aprop )
   {
-    TT_BDF     bdf   = &face->bdf;
-    FT_Size    size  = FT_FACE( face )->size;
-    FT_Error   error = FT_Err_Ok;
+    TT_Face    ttface = (TT_Face)face;
+    TT_BDF     bdf    = &ttface->bdf;
+    FT_Size    size   = FT_FACE_SIZE( face );
+    FT_Error   error  = FT_Err_Ok;
     FT_Byte*   p;
     FT_UInt    count;
     FT_Byte*   strike;
@@ -153,7 +154,7 @@
 
     if ( bdf->loaded == 0 )
     {
-      error = tt_face_load_bdf_props( face, FT_FACE( face )->stream );
+      error = tt_face_load_bdf_props( ttface, FT_FACE_STREAM( face ) );
       if ( error )
         goto Exit;
     }
@@ -248,7 +249,7 @@
 #else /* !TT_CONFIG_OPTION_BDF */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _tt_bdf_dummy;
+  typedef int  tt_bdf_dummy_;
 
 #endif /* !TT_CONFIG_OPTION_BDF */
 
diff --git a/src/sfnt/ttbdf.h b/src/sfnt/ttbdf.h
index 595aeb7..0d7a0ac 100644
--- a/src/sfnt/ttbdf.h
+++ b/src/sfnt/ttbdf.h
@@ -34,7 +34,7 @@
 
 
   FT_LOCAL( FT_Error )
-  tt_face_find_bdf_prop( TT_Face           face,
+  tt_face_find_bdf_prop( FT_Face           face,
                          const char*       property_name,
                          BDF_PropertyRec  *aprop );
 
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
index 820cd08..9ba25dc 100644
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -59,10 +59,14 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap_init( TT_CMap   cmap,
-                FT_Byte*  table )
+  tt_cmap_init( FT_CMap  cmap,    /* TT_CMap */
+                void*    table_ )
   {
-    cmap->data = table;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  table  = (FT_Byte*)table_;
+
+
+    ttcmap->data = table;
     return FT_Err_Ok;
   }
 
@@ -128,21 +132,23 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap0_char_index( TT_CMap    cmap,
+  tt_cmap0_char_index( FT_CMap    cmap,       /* TT_CMap */
                        FT_UInt32  char_code )
   {
-    FT_Byte*  table = cmap->data;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  table  = ttcmap->data;
 
 
     return char_code < 256 ? table[6 + char_code] : 0;
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap0_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap0_char_next( FT_CMap     cmap,        /* TT_CMap */
                       FT_UInt32  *pchar_code )
   {
-    FT_Byte*   table    = cmap->data;
+    TT_CMap    ttcmap   = (TT_CMap)cmap;
+    FT_Byte*   table    = ttcmap->data;
     FT_UInt32  charcode = *pchar_code;
     FT_UInt32  result   = 0;
     FT_UInt    gindex   = 0;
@@ -165,10 +171,11 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap0_get_info( TT_CMap       cmap,
+  tt_cmap0_get_info( FT_CharMap    cmap,       /* TT_CMap */
                      TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 4;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 4;
 
 
     cmap_info->format   = 0;
@@ -453,10 +460,11 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap2_char_index( TT_CMap    cmap,
+  tt_cmap2_char_index( FT_CMap    cmap,       /* TT_CMap */
                        FT_UInt32  char_code )
   {
-    FT_Byte*  table   = cmap->data;
+    TT_CMap   ttcmap  = (TT_CMap)cmap;
+    FT_Byte*  table   = ttcmap->data;
     FT_UInt   result  = 0;
     FT_Byte*  subheader;
 
@@ -491,11 +499,12 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap2_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap2_char_next( FT_CMap     cmap,       /* TT_CMap */
                       FT_UInt32  *pcharcode )
   {
-    FT_Byte*   table    = cmap->data;
+    TT_CMap    ttcmap   = (TT_CMap)cmap;
+    FT_Byte*   table    = ttcmap->data;
     FT_UInt    gindex   = 0;
     FT_UInt32  result   = 0;
     FT_UInt32  charcode = *pcharcode + 1;
@@ -579,10 +588,11 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap2_get_info( TT_CMap       cmap,
+  tt_cmap2_get_info( FT_CharMap    cmap,       /* TT_CMap */
                      TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 4;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 4;
 
 
     cmap_info->format   = 2;
@@ -706,18 +716,20 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap4_init( TT_CMap4  cmap,
-                 FT_Byte*  table )
+  tt_cmap4_init( FT_CMap  cmap,    /* TT_CMap4 */
+                 void*    table_ )
   {
+    TT_CMap4  ttcmap = (TT_CMap4)cmap;
+    FT_Byte*  table  = (FT_Byte*)table_;
     FT_Byte*  p;
 
 
-    cmap->cmap.data    = table;
+    ttcmap->cmap.data = table;
 
-    p                  = table + 6;
-    cmap->num_ranges   = FT_PEEK_USHORT( p ) >> 1;
-    cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
-    cmap->cur_gindex   = 0;
+    p                    = table + 6;
+    ttcmap->num_ranges   = FT_PEEK_USHORT( p ) >> 1;
+    ttcmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
+    ttcmap->cur_gindex   = 0;
 
     return FT_Err_Ok;
   }
@@ -755,7 +767,7 @@
            cmap->cur_start == 0xFFFFU        &&
            cmap->cur_end   == 0xFFFFU        )
       {
-        TT_Face   face  = (TT_Face)cmap->cmap.cmap.charmap.face;
+        TT_Face   face  = (TT_Face)FT_CMAP_FACE( cmap );
         FT_Byte*  limit = face->cmap_table + face->cmap_size;
 
 
@@ -788,15 +800,12 @@
   static void
   tt_cmap4_next( TT_CMap4  cmap )
   {
-    TT_Face   face  = (TT_Face)cmap->cmap.cmap.charmap.face;
+    TT_Face   face  = (TT_Face)FT_CMAP_FACE( cmap );
     FT_Byte*  limit = face->cmap_table + face->cmap_size;
 
     FT_UInt  charcode;
 
 
-    if ( cmap->cur_charcode >= 0xFFFFUL )
-      goto Fail;
-
     charcode = (FT_UInt)cmap->cur_charcode + 1;
 
     if ( charcode < cmap->cur_start )
@@ -882,7 +891,6 @@
         charcode = cmap->cur_start;
     }
 
-  Fail:
     cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
     cmap->cur_gindex   = 0;
   }
@@ -1097,32 +1105,26 @@
                             FT_UInt32*  pcharcode,
                             FT_Bool     next )
   {
-    TT_Face   face  = (TT_Face)cmap->cmap.charmap.face;
+    TT_Face   face  = (TT_Face)FT_CMAP_FACE( cmap );
     FT_Byte*  limit = face->cmap_table + face->cmap_size;
 
 
     FT_UInt    num_segs2, start, end, offset;
     FT_Int     delta;
     FT_UInt    i, num_segs;
-    FT_UInt32  charcode = *pcharcode;
+    FT_UInt32  charcode = *pcharcode + next;
     FT_UInt    gindex   = 0;
     FT_Byte*   p;
     FT_Byte*   q;
 
 
     p = cmap->data + 6;
-    num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
-
-    num_segs = num_segs2 >> 1;
+    num_segs = TT_PEEK_USHORT( p ) >> 1;
 
     if ( !num_segs )
       return 0;
 
-    if ( next )
-      charcode++;
-
-    if ( charcode > 0xFFFFU )
-      return 0;
+    num_segs2 = num_segs << 1;
 
     /* linear search */
     p = cmap->data + 14;               /* ends table   */
@@ -1232,37 +1234,30 @@
                             FT_UInt32*  pcharcode,
                             FT_Bool     next )
   {
-    TT_Face   face  = (TT_Face)cmap->cmap.charmap.face;
+    TT_Face   face  = (TT_Face)FT_CMAP_FACE( cmap );
     FT_Byte*  limit = face->cmap_table + face->cmap_size;
 
     FT_UInt   num_segs2, start, end, offset;
     FT_Int    delta;
     FT_UInt   max, min, mid, num_segs;
-    FT_UInt   charcode = (FT_UInt)*pcharcode;
+    FT_UInt   charcode = (FT_UInt)*pcharcode + next;
     FT_UInt   gindex   = 0;
     FT_Byte*  p;
 
 
     p = cmap->data + 6;
-    num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
+    num_segs = TT_PEEK_USHORT( p ) >> 1;
 
-    if ( !num_segs2 )
+    if ( !num_segs )
       return 0;
 
-    num_segs = num_segs2 >> 1;
-
-    /* make compiler happy */
-    mid = num_segs;
-    end = 0xFFFFU;
-
-    if ( next )
-      charcode++;
+    num_segs2 = num_segs << 1;
 
     min = 0;
     max = num_segs;
 
     /* binary search */
-    while ( min < max )
+    do
     {
       mid    = ( min + max ) >> 1;
       p      = cmap->data + 14 + mid * 2;
@@ -1445,6 +1440,7 @@
         break;
       }
     }
+    while ( min < max );
 
     if ( next )
     {
@@ -1454,12 +1450,8 @@
       /* if `charcode' is not in any segment, then `mid' is */
       /* the segment nearest to `charcode'                  */
 
-      if ( charcode > end )
-      {
-        mid++;
-        if ( mid == num_segs )
-          return 0;
-      }
+      if ( charcode > end && ++mid == num_segs )
+        return 0;
 
       if ( tt_cmap4_set_range( cmap4, mid ) )
       {
@@ -1474,7 +1466,6 @@
           cmap4->cur_gindex = gindex;
         else
         {
-          cmap4->cur_charcode = charcode;
           tt_cmap4_next( cmap4 );
           gindex = cmap4->cur_gindex;
         }
@@ -1489,31 +1480,35 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap4_char_index( TT_CMap    cmap,
+  tt_cmap4_char_index( FT_CMap    cmap,       /* TT_CMap */
                        FT_UInt32  char_code )
   {
+    TT_CMap  ttcmap = (TT_CMap)cmap;
+
+
     if ( char_code >= 0x10000UL )
       return 0;
 
-    if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
-      return tt_cmap4_char_map_linear( cmap, &char_code, 0 );
+    if ( ttcmap->flags & TT_CMAP_FLAG_UNSORTED )
+      return tt_cmap4_char_map_linear( ttcmap, &char_code, 0 );
     else
-      return tt_cmap4_char_map_binary( cmap, &char_code, 0 );
+      return tt_cmap4_char_map_binary( ttcmap, &char_code, 0 );
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap4_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap4_char_next( FT_CMap     cmap,        /* TT_CMap */
                       FT_UInt32  *pchar_code )
   {
+    TT_CMap  ttcmap = (TT_CMap)cmap;
     FT_UInt  gindex;
 
 
     if ( *pchar_code >= 0xFFFFU )
       return 0;
 
-    if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
-      gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 );
+    if ( ttcmap->flags & TT_CMAP_FLAG_UNSORTED )
+      gindex = tt_cmap4_char_map_linear( ttcmap, pchar_code, 1 );
     else
     {
       TT_CMap4  cmap4 = (TT_CMap4)cmap;
@@ -1528,7 +1523,7 @@
           *pchar_code = cmap4->cur_charcode;
       }
       else
-        gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 );
+        gindex = tt_cmap4_char_map_binary( ttcmap, pchar_code, 1 );
     }
 
     return gindex;
@@ -1536,10 +1531,11 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap4_get_info( TT_CMap       cmap,
+  tt_cmap4_get_info( FT_CharMap    cmap,       /* TT_CMap */
                      TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 4;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 4;
 
 
     cmap_info->format   = 4;
@@ -1640,10 +1636,11 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap6_char_index( TT_CMap    cmap,
+  tt_cmap6_char_index( FT_CMap    cmap,       /* TT_CMap */
                        FT_UInt32  char_code )
   {
-    FT_Byte*  table  = cmap->data;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  table  = ttcmap->data;
     FT_UInt   result = 0;
     FT_Byte*  p      = table + 6;
     FT_UInt   start  = TT_NEXT_USHORT( p );
@@ -1661,11 +1658,12 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap6_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap6_char_next( FT_CMap     cmap,        /* TT_CMap */
                       FT_UInt32  *pchar_code )
   {
-    FT_Byte*   table     = cmap->data;
+    TT_CMap    ttcmap    = (TT_CMap)cmap;
+    FT_Byte*   table     = ttcmap->data;
     FT_UInt32  result    = 0;
     FT_UInt32  char_code = *pchar_code + 1;
     FT_UInt    gindex    = 0;
@@ -1706,10 +1704,11 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap6_get_info( TT_CMap       cmap,
+  tt_cmap6_get_info( FT_CharMap    cmap,       /* TT_CMap */
                      TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 4;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 4;
 
 
     cmap_info->format   = 6;
@@ -1900,10 +1899,11 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap8_char_index( TT_CMap    cmap,
+  tt_cmap8_char_index( FT_CMap    cmap,       /* TT_CMap */
                        FT_UInt32  char_code )
   {
-    FT_Byte*   table      = cmap->data;
+    TT_CMap    ttcmap     = (TT_CMap)cmap;
+    FT_Byte*   table      = ttcmap->data;
     FT_UInt    result     = 0;
     FT_Byte*   p          = table + 8204;
     FT_UInt32  num_groups = TT_NEXT_ULONG( p );
@@ -1932,15 +1932,16 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap8_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap8_char_next( FT_CMap     cmap,        /* TT_CMap */
                       FT_UInt32  *pchar_code )
   {
-    FT_Face    face       = cmap->cmap.charmap.face;
+    TT_CMap    ttcmap     = (TT_CMap)cmap;
+    FT_Face    face       = FT_CMAP_FACE( cmap );
     FT_UInt32  result     = 0;
     FT_UInt32  char_code;
     FT_UInt    gindex     = 0;
-    FT_Byte*   table      = cmap->data;
+    FT_Byte*   table      = ttcmap->data;
     FT_Byte*   p          = table + 8204;
     FT_UInt32  num_groups = TT_NEXT_ULONG( p );
     FT_UInt32  start, end, start_id;
@@ -2000,10 +2001,11 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap8_get_info( TT_CMap       cmap,
+  tt_cmap8_get_info( FT_CharMap    cmap,       /* TT_CMap */
                      TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 8;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 8;
 
 
     cmap_info->format   = 8;
@@ -2104,10 +2106,11 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap10_char_index( TT_CMap    cmap,
+  tt_cmap10_char_index( FT_CMap    cmap,       /* TT_CMap */
                         FT_UInt32  char_code )
   {
-    FT_Byte*   table  = cmap->data;
+    TT_CMap    ttcmap = (TT_CMap)cmap;
+    FT_Byte*   table  = ttcmap->data;
     FT_UInt    result = 0;
     FT_Byte*   p      = table + 12;
     FT_UInt32  start  = TT_NEXT_ULONG( p );
@@ -2130,11 +2133,12 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap10_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap10_char_next( FT_CMap     cmap,        /* TT_CMap */
                        FT_UInt32  *pchar_code )
   {
-    FT_Byte*   table     = cmap->data;
+    TT_CMap    ttcmap    = (TT_CMap)cmap;
+    FT_Byte*   table     = ttcmap->data;
     FT_UInt32  char_code;
     FT_UInt    gindex    = 0;
     FT_Byte*   p         = table + 12;
@@ -2172,10 +2176,11 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap10_get_info( TT_CMap       cmap,
+  tt_cmap10_get_info( FT_CharMap    cmap,       /* TT_CMap */
                       TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 8;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 8;
 
 
     cmap_info->format   = 10;
@@ -2253,15 +2258,19 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap12_init( TT_CMap12  cmap,
-                  FT_Byte*   table )
+  tt_cmap12_init( FT_CMap  cmap,    /* TT_CMap12 */
+                  void*    table_ )
   {
-    cmap->cmap.data  = table;
+    TT_CMap12  ttcmap = (TT_CMap12)cmap;
+    FT_Byte*   table  = (FT_Byte*)table_;
 
-    table           += 12;
-    cmap->num_groups = FT_PEEK_ULONG( table );
 
-    cmap->valid      = 0;
+    ttcmap->cmap.data  = table;
+
+    table             += 12;
+    ttcmap->num_groups = FT_PEEK_ULONG( table );
+
+    ttcmap->valid      = 0;
 
     return FT_Err_Ok;
   }
@@ -2331,23 +2340,21 @@
   /* cmap->cur_group should be set up properly by caller         */
   /*                                                             */
   static void
-  tt_cmap12_next( TT_CMap12  cmap )
+  tt_cmap12_next( FT_CMap  cmap )    /* TT_CMap12 */
   {
-    FT_Face   face = cmap->cmap.cmap.charmap.face;
-    FT_Byte*  p;
-    FT_ULong  start, end, start_id, char_code;
-    FT_ULong  n;
-    FT_UInt   gindex;
+    TT_CMap12  ttcmap = (TT_CMap12)cmap;
+    FT_Face    face   = FT_CMAP_FACE( cmap );
+    FT_Byte*   p;
+    FT_ULong   start, end, start_id, char_code;
+    FT_ULong   n;
+    FT_UInt    gindex;
 
 
-    if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
-      goto Fail;
+    char_code = ttcmap->cur_charcode + 1;
 
-    char_code = cmap->cur_charcode + 1;
-
-    for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
+    for ( n = ttcmap->cur_group; n < ttcmap->num_groups; n++ )
     {
-      p        = cmap->cmap.data + 16 + 12 * n;
+      p        = ttcmap->cmap.data + 16 + 12 * n;
       start    = TT_NEXT_ULONG( p );
       end      = TT_NEXT_ULONG( p );
       start_id = TT_PEEK_ULONG( p );
@@ -2379,16 +2386,16 @@
         if ( gindex >= (FT_UInt)face->num_glyphs )
           continue;
 
-        cmap->cur_charcode = char_code;
-        cmap->cur_gindex   = gindex;
-        cmap->cur_group    = n;
+        ttcmap->cur_charcode = char_code;
+        ttcmap->cur_gindex   = gindex;
+        ttcmap->cur_group    = n;
 
         return;
       }
     }
 
   Fail:
-    cmap->valid = 0;
+    ttcmap->valid = 0;
   }
 
 
@@ -2400,7 +2407,7 @@
     FT_UInt    gindex     = 0;
     FT_Byte*   p          = cmap->data + 12;
     FT_UInt32  num_groups = TT_PEEK_ULONG( p );
-    FT_UInt32  char_code  = *pchar_code;
+    FT_UInt32  char_code  = *pchar_code + next;
     FT_UInt32  start, end, start_id;
     FT_UInt32  max, min, mid;
 
@@ -2408,23 +2415,11 @@
     if ( !num_groups )
       return 0;
 
-    /* make compiler happy */
-    mid = num_groups;
-    end = 0xFFFFFFFFUL;
-
-    if ( next )
-    {
-      if ( char_code >= 0xFFFFFFFFUL )
-        return 0;
-
-      char_code++;
-    }
-
     min = 0;
     max = num_groups;
 
     /* binary search */
-    while ( min < max )
+    do
     {
       mid = ( min + max ) >> 1;
       p   = cmap->data + 16 + 12 * mid;
@@ -2448,22 +2443,19 @@
         break;
       }
     }
+    while ( min < max );
 
     if ( next )
     {
-      FT_Face    face   = cmap->cmap.charmap.face;
+      FT_Face    face   = FT_CMAP_FACE( cmap );
       TT_CMap12  cmap12 = (TT_CMap12)cmap;
 
 
       /* if `char_code' is not in any group, then `mid' is */
       /* the group nearest to `char_code'                  */
 
-      if ( char_code > end )
-      {
-        mid++;
-        if ( mid == num_groups )
-          return 0;
-      }
+      if ( char_code > end && ++mid == num_groups )
+        return 0;
 
       cmap12->valid        = 1;
       cmap12->cur_charcode = char_code;
@@ -2474,7 +2466,7 @@
 
       if ( !gindex )
       {
-        tt_cmap12_next( cmap12 );
+        tt_cmap12_next( FT_CMAP( cmap12 ) );
 
         if ( cmap12->valid )
           gindex = cmap12->cur_gindex;
@@ -2490,25 +2482,28 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap12_char_index( TT_CMap    cmap,
+  tt_cmap12_char_index( FT_CMap    cmap,       /* TT_CMap */
                         FT_UInt32  char_code )
   {
-    return tt_cmap12_char_map_binary( cmap, &char_code, 0 );
+    return tt_cmap12_char_map_binary( (TT_CMap)cmap, &char_code, 0 );
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap12_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap12_char_next( FT_CMap     cmap,        /* TT_CMap12 */
                        FT_UInt32  *pchar_code )
   {
     TT_CMap12  cmap12 = (TT_CMap12)cmap;
     FT_UInt    gindex;
 
 
+    if ( *pchar_code >= 0xFFFFFFFFUL )
+      return 0;
+
     /* no need to search */
     if ( cmap12->valid && cmap12->cur_charcode == *pchar_code )
     {
-      tt_cmap12_next( cmap12 );
+      tt_cmap12_next( FT_CMAP( cmap12 ) );
       if ( cmap12->valid )
       {
         gindex      = cmap12->cur_gindex;
@@ -2518,17 +2513,18 @@
         gindex = 0;
     }
     else
-      gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 );
+      gindex = tt_cmap12_char_map_binary( (TT_CMap)cmap, pchar_code, 1 );
 
     return gindex;
   }
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap12_get_info( TT_CMap       cmap,
+  tt_cmap12_get_info( FT_CharMap    cmap,       /* TT_CMap */
                       TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 8;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 8;
 
 
     cmap_info->format   = 12;
@@ -2606,15 +2602,19 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap13_init( TT_CMap13  cmap,
-                  FT_Byte*   table )
+  tt_cmap13_init( FT_CMap  cmap,    /* TT_CMap13 */
+                  void*    table_ )
   {
-    cmap->cmap.data  = table;
+    TT_CMap13  ttcmap = (TT_CMap13)cmap;
+    FT_Byte*   table  = (FT_Byte*)table_;
 
-    table           += 12;
-    cmap->num_groups = FT_PEEK_ULONG( table );
 
-    cmap->valid      = 0;
+    ttcmap->cmap.data  = table;
+
+    table             += 12;
+    ttcmap->num_groups = FT_PEEK_ULONG( table );
+
+    ttcmap->valid      = 0;
 
     return FT_Err_Ok;
   }
@@ -2679,23 +2679,21 @@
   /* cmap->cur_group should be set up properly by caller         */
   /*                                                             */
   static void
-  tt_cmap13_next( TT_CMap13  cmap )
+  tt_cmap13_next( FT_CMap  cmap )    /* TT_CMap13 */
   {
-    FT_Face   face = cmap->cmap.cmap.charmap.face;
-    FT_Byte*  p;
-    FT_ULong  start, end, glyph_id, char_code;
-    FT_ULong  n;
-    FT_UInt   gindex;
+    TT_CMap13  ttcmap = (TT_CMap13)cmap;
+    FT_Face    face = FT_CMAP_FACE( cmap );
+    FT_Byte*   p;
+    FT_ULong   start, end, glyph_id, char_code;
+    FT_ULong   n;
+    FT_UInt    gindex;
 
 
-    if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
-      goto Fail;
+    char_code = ttcmap->cur_charcode + 1;
 
-    char_code = cmap->cur_charcode + 1;
-
-    for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
+    for ( n = ttcmap->cur_group; n < ttcmap->num_groups; n++ )
     {
-      p        = cmap->cmap.data + 16 + 12 * n;
+      p        = ttcmap->cmap.data + 16 + 12 * n;
       start    = TT_NEXT_ULONG( p );
       end      = TT_NEXT_ULONG( p );
       glyph_id = TT_PEEK_ULONG( p );
@@ -2709,17 +2707,16 @@
 
         if ( gindex && gindex < (FT_UInt)face->num_glyphs )
         {
-          cmap->cur_charcode = char_code;
-          cmap->cur_gindex   = gindex;
-          cmap->cur_group    = n;
+          ttcmap->cur_charcode = char_code;
+          ttcmap->cur_gindex   = gindex;
+          ttcmap->cur_group    = n;
 
           return;
         }
       }
     }
 
-  Fail:
-    cmap->valid = 0;
+    ttcmap->valid = 0;
   }
 
 
@@ -2731,7 +2728,7 @@
     FT_UInt    gindex     = 0;
     FT_Byte*   p          = cmap->data + 12;
     FT_UInt32  num_groups = TT_PEEK_ULONG( p );
-    FT_UInt32  char_code  = *pchar_code;
+    FT_UInt32  char_code  = *pchar_code + next;
     FT_UInt32  start, end;
     FT_UInt32  max, min, mid;
 
@@ -2739,23 +2736,11 @@
     if ( !num_groups )
       return 0;
 
-    /* make compiler happy */
-    mid = num_groups;
-    end = 0xFFFFFFFFUL;
-
-    if ( next )
-    {
-      if ( char_code >= 0xFFFFFFFFUL )
-        return 0;
-
-      char_code++;
-    }
-
     min = 0;
     max = num_groups;
 
     /* binary search */
-    while ( min < max )
+    do
     {
       mid = ( min + max ) >> 1;
       p   = cmap->data + 16 + 12 * mid;
@@ -2774,6 +2759,7 @@
         break;
       }
     }
+    while ( min < max );
 
     if ( next )
     {
@@ -2784,12 +2770,8 @@
       /* if `char_code' is not in any group, then `mid' is */
       /* the group nearest to `char_code'                  */
 
-      if ( char_code > end )
-      {
-        mid++;
-        if ( mid == num_groups )
-          return 0;
-      }
+      if ( char_code > end && ++mid == num_groups )
+        return 0;
 
       cmap13->valid        = 1;
       cmap13->cur_charcode = char_code;
@@ -2800,7 +2782,7 @@
 
       if ( !gindex )
       {
-        tt_cmap13_next( cmap13 );
+        tt_cmap13_next( FT_CMAP( cmap13 ) );
 
         if ( cmap13->valid )
           gindex = cmap13->cur_gindex;
@@ -2816,25 +2798,28 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap13_char_index( TT_CMap    cmap,
+  tt_cmap13_char_index( FT_CMap    cmap,       /* TT_CMap */
                         FT_UInt32  char_code )
   {
-    return tt_cmap13_char_map_binary( cmap, &char_code, 0 );
+    return tt_cmap13_char_map_binary( (TT_CMap)cmap, &char_code, 0 );
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap13_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap13_char_next( FT_CMap     cmap,        /* TT_CMap13 */
                        FT_UInt32  *pchar_code )
   {
     TT_CMap13  cmap13 = (TT_CMap13)cmap;
     FT_UInt    gindex;
 
 
+    if ( *pchar_code >= 0xFFFFFFFFUL )
+      return 0;
+
     /* no need to search */
     if ( cmap13->valid && cmap13->cur_charcode == *pchar_code )
     {
-      tt_cmap13_next( cmap13 );
+      tt_cmap13_next( FT_CMAP( cmap13 ) );
       if ( cmap13->valid )
       {
         gindex      = cmap13->cur_gindex;
@@ -2844,17 +2829,18 @@
         gindex = 0;
     }
     else
-      gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 );
+      gindex = tt_cmap13_char_map_binary( (TT_CMap)cmap, pchar_code, 1 );
 
     return gindex;
   }
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap13_get_info( TT_CMap       cmap,
+  tt_cmap13_get_info( FT_CharMap    cmap,       /* TT_CMap */
                       TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 8;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 8;
 
 
     cmap_info->format   = 13;
@@ -2969,14 +2955,15 @@
 
 
   FT_CALLBACK_DEF( void )
-  tt_cmap14_done( TT_CMap14  cmap )
+  tt_cmap14_done( FT_CMap  cmap )    /* TT_CMap14 */
   {
-    FT_Memory  memory = cmap->memory;
+    TT_CMap14  ttcmap = (TT_CMap14)cmap;
+    FT_Memory  memory = ttcmap->memory;
 
 
-    cmap->max_results = 0;
-    if ( memory && cmap->results )
-      FT_FREE( cmap->results );
+    ttcmap->max_results = 0;
+    if ( memory && ttcmap->results )
+      FT_FREE( ttcmap->results );
   }
 
 
@@ -3004,15 +2991,19 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap14_init( TT_CMap14  cmap,
-                  FT_Byte*   table )
+  tt_cmap14_init( FT_CMap  cmap,    /* TT_CMap14 */
+                  void*    table_ )
   {
-    cmap->cmap.data = table;
+    TT_CMap14  ttcmap = (TT_CMap14)cmap;
+    FT_Byte*   table  = (FT_Byte*)table_;
 
-    table               += 6;
-    cmap->num_selectors  = FT_PEEK_ULONG( table );
-    cmap->max_results    = 0;
-    cmap->results        = NULL;
+
+    ttcmap->cmap.data = table;
+
+    table                 += 6;
+    ttcmap->num_selectors  = FT_PEEK_ULONG( table );
+    ttcmap->max_results    = 0;
+    ttcmap->results        = NULL;
 
     return FT_Err_Ok;
   }
@@ -3142,7 +3133,7 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap14_char_index( TT_CMap    cmap,
+  tt_cmap14_char_index( FT_CMap    cmap,
                         FT_UInt32  char_code )
   {
     FT_UNUSED( cmap );
@@ -3153,8 +3144,8 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap14_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap14_char_next( FT_CMap     cmap,
                        FT_UInt32  *pchar_code )
   {
     FT_UNUSED( cmap );
@@ -3166,7 +3157,7 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap14_get_info( TT_CMap       cmap,
+  tt_cmap14_get_info( FT_CharMap    cmap,
                       TT_CMapInfo  *cmap_info )
   {
     FT_UNUSED( cmap );
@@ -3280,12 +3271,16 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap14_char_var_index( TT_CMap    cmap,
-                            TT_CMap    ucmap,
+  tt_cmap14_char_var_index( FT_CMap    cmap,             /* TT_CMap */
+                            FT_CMap    ucmap,            /* TT_CMap */
                             FT_UInt32  charcode,
                             FT_UInt32  variantSelector )
   {
-    FT_Byte*  p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
+    TT_CMap  ttcmap  = (TT_CMap)cmap;
+    TT_CMap  ttucmap = (TT_CMap)ucmap;
+
+    FT_Byte*  p = tt_cmap14_find_variant( ttcmap->data + 6,
+                                          variantSelector );
     FT_ULong  defOff;
     FT_ULong  nondefOff;
 
@@ -3296,16 +3291,16 @@
     defOff    = TT_NEXT_ULONG( p );
     nondefOff = TT_PEEK_ULONG( p );
 
-    if ( defOff != 0                                                    &&
-         tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
+    if ( defOff != 0                                                      &&
+         tt_cmap14_char_map_def_binary( ttcmap->data + defOff, charcode ) )
     {
       /* This is the default variant of this charcode.  GID not stored */
       /* here; stored in the normal Unicode charmap instead.           */
-      return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode );
+      return ttucmap->cmap.clazz->char_index( &ttucmap->cmap, charcode );
     }
 
     if ( nondefOff != 0 )
-      return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
+      return tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff,
                                                charcode );
 
     return 0;
@@ -3313,11 +3308,13 @@
 
 
   FT_CALLBACK_DEF( FT_Int )
-  tt_cmap14_char_var_isdefault( TT_CMap    cmap,
+  tt_cmap14_char_var_isdefault( FT_CMap    cmap,             /* TT_CMap */
                                 FT_UInt32  charcode,
                                 FT_UInt32  variantSelector )
   {
-    FT_Byte*  p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = tt_cmap14_find_variant( ttcmap->data + 6,
+                                               variantSelector );
     FT_ULong  defOff;
     FT_ULong  nondefOff;
 
@@ -3328,13 +3325,13 @@
     defOff    = TT_NEXT_ULONG( p );
     nondefOff = TT_NEXT_ULONG( p );
 
-    if ( defOff != 0                                                    &&
-         tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
+    if ( defOff != 0                                                      &&
+         tt_cmap14_char_map_def_binary( ttcmap->data + defOff, charcode ) )
       return 1;
 
-    if ( nondefOff != 0                                            &&
-         tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
-                                           charcode ) != 0         )
+    if ( nondefOff != 0                                              &&
+         tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff,
+                                           charcode ) != 0           )
       return 0;
 
     return -1;
@@ -3342,12 +3339,13 @@
 
 
   FT_CALLBACK_DEF( FT_UInt32* )
-  tt_cmap14_variants( TT_CMap    cmap,
+  tt_cmap14_variants( FT_CMap    cmap,    /* TT_CMap14 */
                       FT_Memory  memory )
   {
+    TT_CMap     ttcmap = (TT_CMap)cmap;
     TT_CMap14   cmap14 = (TT_CMap14)cmap;
     FT_UInt32   count  = cmap14->num_selectors;
-    FT_Byte*    p      = cmap->data + 10;
+    FT_Byte*    p      = ttcmap->data + 10;
     FT_UInt32*  result;
     FT_UInt32   i;
 
@@ -3368,13 +3366,14 @@
 
 
   FT_CALLBACK_DEF( FT_UInt32 * )
-  tt_cmap14_char_variants( TT_CMap    cmap,
+  tt_cmap14_char_variants( FT_CMap    cmap,      /* TT_CMap14 */
                            FT_Memory  memory,
                            FT_UInt32  charCode )
   {
-    TT_CMap14   cmap14 = (TT_CMap14)  cmap;
+    TT_CMap     ttcmap = (TT_CMap)cmap;
+    TT_CMap14   cmap14 = (TT_CMap14)cmap;
     FT_UInt32   count  = cmap14->num_selectors;
-    FT_Byte*    p      = cmap->data + 10;
+    FT_Byte*    p      = ttcmap->data + 10;
     FT_UInt32*  q;
 
 
@@ -3388,12 +3387,12 @@
       FT_ULong   nondefOff = TT_NEXT_ULONG( p );
 
 
-      if ( ( defOff != 0                                               &&
-             tt_cmap14_char_map_def_binary( cmap->data + defOff,
-                                            charCode )                 ) ||
-           ( nondefOff != 0                                            &&
-             tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
-                                               charCode ) != 0         ) )
+      if ( ( defOff != 0                                                 &&
+             tt_cmap14_char_map_def_binary( ttcmap->data + defOff,
+                                            charCode )                   ) ||
+           ( nondefOff != 0                                              &&
+             tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff,
+                                               charCode ) != 0           ) )
       {
         q[0] = varSel;
         q++;
@@ -3489,15 +3488,16 @@
 
 
   FT_CALLBACK_DEF( FT_UInt32 * )
-  tt_cmap14_variant_chars( TT_CMap    cmap,
+  tt_cmap14_variant_chars( FT_CMap    cmap,             /* TT_CMap */
                            FT_Memory  memory,
                            FT_UInt32  variantSelector )
   {
-    FT_Byte    *p  = tt_cmap14_find_variant( cmap->data + 6,
-                                             variantSelector );
-    FT_Int      i;
-    FT_ULong    defOff;
-    FT_ULong    nondefOff;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte  *p      = tt_cmap14_find_variant( ttcmap->data + 6,
+                                               variantSelector );
+    FT_Int    i;
+    FT_ULong  defOff;
+    FT_ULong  nondefOff;
 
 
     if ( !p )
@@ -3510,16 +3510,16 @@
       return NULL;
 
     if ( defOff == 0 )
-      return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
+      return tt_cmap14_get_nondef_chars( ttcmap, ttcmap->data + nondefOff,
                                          memory );
     else if ( nondefOff == 0 )
-      return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
+      return tt_cmap14_get_def_chars( ttcmap, ttcmap->data + defOff,
                                       memory );
     else
     {
       /* Both a default and a non-default glyph set?  That's probably not */
       /* good font design, but the spec allows for it...                  */
-      TT_CMap14  cmap14 = (TT_CMap14) cmap;
+      TT_CMap14  cmap14 = (TT_CMap14)cmap;
       FT_UInt32  numRanges;
       FT_UInt32  numMappings;
       FT_UInt32  duni;
@@ -3531,18 +3531,18 @@
       FT_UInt32  *ret;
 
 
-      p  = cmap->data + nondefOff;
-      dp = cmap->data + defOff;
+      p  = ttcmap->data + nondefOff;
+      dp = ttcmap->data + defOff;
 
       numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
       dcnt        = tt_cmap14_def_char_count( dp );
       numRanges   = (FT_UInt32)TT_NEXT_ULONG( dp );
 
       if ( numMappings == 0 )
-        return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
+        return tt_cmap14_get_def_chars( ttcmap, ttcmap->data + defOff,
                                         memory );
       if ( dcnt == 0 )
-        return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
+        return tt_cmap14_get_nondef_chars( ttcmap, ttcmap->data + nondefOff,
                                            memory );
 
       if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) )
@@ -3664,9 +3664,10 @@
 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
 
   FT_CALLBACK_DEF( const char * )
-  tt_get_glyph_name( TT_Face  face,
+  tt_get_glyph_name( void*    face_,   /* TT_Face */
                      FT_UInt  idx )
   {
+    TT_Face     face   = (TT_Face)face_;
     FT_String*  PSname = NULL;
 
 
@@ -3677,12 +3678,13 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap_unicode_init( PS_Unicodes  unicodes,
-                        FT_Pointer   pointer )
+  tt_cmap_unicode_init( FT_CMap     cmap,     /* PS_Unicodes */
+                        FT_Pointer  pointer )
   {
-    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
-    FT_Memory           memory  = FT_FACE_MEMORY( face );
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    TT_Face             face     = (TT_Face)FT_CMAP_FACE( cmap );
+    FT_Memory           memory   = FT_FACE_MEMORY( face );
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
 
     FT_UNUSED( pointer );
 
@@ -3693,17 +3695,18 @@
     return psnames->unicodes_init( memory,
                                    unicodes,
                                    face->root.num_glyphs,
-                                   (PS_GetGlyphNameFunc)&tt_get_glyph_name,
+                                   &tt_get_glyph_name,
                                    (PS_FreeGlyphNameFunc)NULL,
                                    (FT_Pointer)face );
   }
 
 
   FT_CALLBACK_DEF( void )
-  tt_cmap_unicode_done( PS_Unicodes  unicodes )
+  tt_cmap_unicode_done( FT_CMap  cmap )    /* PS_Unicodes */
   {
-    FT_Face    face   = FT_CMAP_FACE( unicodes );
-    FT_Memory  memory = FT_FACE_MEMORY( face );
+    PS_Unicodes  unicodes = (PS_Unicodes)cmap;
+    FT_Face      face     = FT_CMAP_FACE( cmap );
+    FT_Memory    memory   = FT_FACE_MEMORY( face );
 
 
     FT_FREE( unicodes->maps );
@@ -3712,23 +3715,25 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap_unicode_char_index( PS_Unicodes  unicodes,
-                              FT_UInt32    char_code )
+  tt_cmap_unicode_char_index( FT_CMap    cmap,       /* PS_Unicodes */
+                              FT_UInt32  char_code )
   {
-    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    TT_Face             face     = (TT_Face)FT_CMAP_FACE( cmap );
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
 
 
     return psnames->unicodes_char_index( unicodes, char_code );
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap_unicode_char_next( PS_Unicodes  unicodes,
-                             FT_UInt32   *pchar_code )
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap_unicode_char_next( FT_CMap     cmap,        /* PS_Unicodes */
+                             FT_UInt32  *pchar_code )
   {
-    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    TT_Face             face     = (TT_Face)FT_CMAP_FACE( cmap );
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
 
 
     return psnames->unicodes_char_next( unicodes, pchar_code );
@@ -3883,7 +3888,7 @@
   tt_get_cmap_info( FT_CharMap    charmap,
                     TT_CMapInfo  *cmap_info )
   {
-    FT_CMap        cmap  = (FT_CMap)charmap;
+    FT_CMap        cmap  = FT_CMAP( charmap );
     TT_CMap_Class  clazz = (TT_CMap_Class)cmap->clazz;
 
 
diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c
index 5d98dca..281e713 100644
--- a/src/sfnt/ttcolr.c
+++ b/src/sfnt/ttcolr.c
@@ -229,7 +229,7 @@
 
       base_glyphs_offset_v1 = FT_NEXT_ULONG( p );
 
-      if ( base_glyphs_offset_v1 + 4 >= table_size )
+      if ( base_glyphs_offset_v1 >= table_size - 4 )
         goto InvalidTable;
 
       p1                 = (FT_Byte*)( table + base_glyphs_offset_v1 );
@@ -249,7 +249,7 @@
 
       if ( layer_offset_v1 )
       {
-        if ( layer_offset_v1 + 4 >= table_size )
+        if ( layer_offset_v1 >= table_size - 4 )
           goto InvalidTable;
 
         p1            = (FT_Byte*)( table + layer_offset_v1 );
@@ -699,7 +699,7 @@
                                              item_deltas ) )
           return 0;
 
-        apaint->u.solid.color.alpha += item_deltas[0];
+        apaint->u.solid.color.alpha += (FT_F2Dot14)item_deltas[0];
       }
 #endif
 
@@ -1646,7 +1646,7 @@
           return 0;
 
         color_stop->stop_offset += F2DOT14_TO_FIXED( item_deltas[0] );
-        color_stop->color.alpha += item_deltas[1];
+        color_stop->color.alpha += (FT_F2Dot14)item_deltas[1];
       }
 #else
       FT_UNUSED( var_index_base );
@@ -1914,7 +1914,7 @@
 #else /* !TT_CONFIG_OPTION_COLOR_LAYERS */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _tt_colr_dummy;
+  typedef int  tt_colr_dummy_;
 
 #endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */
 
diff --git a/src/sfnt/ttcpal.c b/src/sfnt/ttcpal.c
index 4279bc0..46ae085 100644
--- a/src/sfnt/ttcpal.c
+++ b/src/sfnt/ttcpal.c
@@ -303,7 +303,7 @@
 #else /* !TT_CONFIG_OPTION_COLOR_LAYERS */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _tt_cpal_dummy;
+  typedef int  tt_cpal_dummy_;
 
 #endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */
 
diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c
index 14f625c..7b44e9c 100644
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -504,6 +504,13 @@
 
     FT_FRAME_EXIT();
 
+    if ( !valid_entries )
+    {
+      FT_TRACE2(( "tt_face_load_font_dir: no valid tables found\n" ));
+      error = FT_THROW( Unknown_File_Format );
+      goto Exit;
+    }
+
     FT_TRACE2(( "table directory loaded\n" ));
     FT_TRACE2(( "\n" ));
 
diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c
index 0e17c6f..1dfad42 100644
--- a/src/sfnt/ttpost.c
+++ b/src/sfnt/ttpost.c
@@ -156,86 +156,66 @@
 
 
   static FT_Error
-  load_format_20( TT_Face    face,
-                  FT_Stream  stream,
-                  FT_ULong   post_len )
+  load_format_20( TT_Post_Names  names,
+                  FT_Stream      stream,
+                  FT_UShort      num_glyphs,
+                  FT_ULong       post_len )
   {
     FT_Memory   memory = stream->memory;
     FT_Error    error;
 
-    FT_Int      num_glyphs;
-    FT_UShort   num_names;
+    FT_UShort   n;
+    FT_UShort   num_names = 0;
 
     FT_UShort*  glyph_indices = NULL;
-    FT_Char**   name_strings  = NULL;
-    FT_Byte*    strings       = NULL;
+    FT_Byte**   name_strings  = NULL;
+    FT_Byte*    q;
 
 
-    if ( FT_READ_USHORT( num_glyphs ) )
-      goto Exit;
-
-    /* UNDOCUMENTED!  The number of glyphs in this table can be smaller */
-    /* than the value in the maxp table (cf. cyberbit.ttf).             */
-
-    /* There already exist fonts which have more than 32768 glyph names */
-    /* in this table, so the test for this threshold has been dropped.  */
-
-    if ( num_glyphs > face->max_profile.numGlyphs  ||
-         (FT_ULong)num_glyphs * 2UL > post_len - 2 )
+    if ( (FT_ULong)num_glyphs * 2 > post_len )
     {
       error = FT_THROW( Invalid_File_Format );
       goto Exit;
     }
 
-    /* load the indices */
+    /* load the indices and note their maximum */
+    if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) ||
+         FT_FRAME_ENTER( num_glyphs * 2 )           )
+      goto Fail;
+
+    q = (FT_Byte*)stream->cursor;
+
+    for ( n = 0; n < num_glyphs; n++ )
     {
-      FT_Int  n;
+      FT_UShort  idx = FT_NEXT_USHORT( q );
 
 
-      if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) ||
-           FT_FRAME_ENTER( num_glyphs * 2L )          )
-        goto Fail;
+      if ( idx > num_names )
+        num_names = idx;
 
-      for ( n = 0; n < num_glyphs; n++ )
-        glyph_indices[n] = FT_GET_USHORT();
-
-      FT_FRAME_EXIT();
+      glyph_indices[n] = idx;
     }
 
-    /* compute number of names stored in table */
-    {
-      FT_Int  n;
+    FT_FRAME_EXIT();
 
-
-      num_names = 0;
-
-      for ( n = 0; n < num_glyphs; n++ )
-      {
-        FT_Int  idx;
-
-
-        idx = glyph_indices[n];
-        if ( idx >= 258 )
-        {
-          idx -= 257;
-          if ( idx > num_names )
-            num_names = (FT_UShort)idx;
-        }
-      }
-    }
+    /* compute number of names stored in the table */
+    num_names = num_names > 257 ? num_names - 257 : 0;
 
     /* now load the name strings */
     if ( num_names )
     {
-      FT_UShort  n;
       FT_ULong   p;
+      FT_Byte*   strings;
 
 
-      post_len -= (FT_ULong)num_glyphs * 2UL + 2;
+      post_len -= (FT_ULong)num_glyphs * 2;
 
-      if ( FT_QALLOC( strings, post_len + 1 )       ||
-           FT_STREAM_READ( strings, post_len )      ||
-           FT_QNEW_ARRAY( name_strings, num_names ) )
+      if ( FT_QALLOC( name_strings, num_names * sizeof ( FT_Byte* ) +
+                                    post_len + 1 ) )
+        goto Fail;
+
+      strings = (FT_Byte*)( name_strings + num_names );
+      if ( FT_STREAM_READ( strings, post_len ) )
         goto Fail;
 
       /* convert from Pascal- to C-strings and set pointers */
@@ -251,7 +231,7 @@
         }
 
         strings[p]      = 0;
-        name_strings[n] = (FT_Char*)strings + p + 1;
+        name_strings[n] = strings + p + 1;
         p              += len + 1;
       }
       strings[post_len] = 0;
@@ -259,40 +239,24 @@
       /* deal with missing or insufficient string data */
       if ( n < num_names )
       {
-        if ( post_len == 0 )
-        {
-          /* fake empty string */
-          if ( FT_QREALLOC( strings, 1, 2 ) )
-            goto Fail;
+        FT_TRACE4(( "load_format_20: %hu PostScript names are truncated\n",
+                    num_names - n ));
 
-          post_len          = 1;
-          strings[post_len] = 0;
-        }
-
-        FT_ERROR(( "load_format_20:"
-                   " all entries in post table are already parsed,"
-                   " using NULL names for gid %d - %d\n",
-                    n, num_names - 1 ));
         for ( ; n < num_names; n++ )
-          name_strings[n] = (FT_Char*)strings + post_len;
+          name_strings[n] = strings + post_len;
       }
     }
 
     /* all right, set table fields and exit successfully */
-    {
-      TT_Post_20  table = &face->postscript_names.names.format_20;
+    names->num_glyphs    = num_glyphs;
+    names->num_names     = num_names;
+    names->glyph_indices = glyph_indices;
+    names->glyph_names   = name_strings;
 
-
-      table->num_glyphs    = (FT_UShort)num_glyphs;
-      table->num_names     = (FT_UShort)num_names;
-      table->glyph_indices = glyph_indices;
-      table->glyph_names   = name_strings;
-    }
     return FT_Err_Ok;
 
   Fail:
     FT_FREE( name_strings );
-    FT_FREE( strings );
     FT_FREE( glyph_indices );
 
   Exit:
@@ -301,66 +265,55 @@
 
 
   static FT_Error
-  load_format_25( TT_Face    face,
-                  FT_Stream  stream,
-                  FT_ULong   post_len )
+  load_format_25( TT_Post_Names  names,
+                  FT_Stream      stream,
+                  FT_UShort      num_glyphs,
+                  FT_ULong       post_len )
   {
     FT_Memory  memory = stream->memory;
     FT_Error   error;
 
-    FT_Int     num_glyphs;
-    FT_Char*   offset_table = NULL;
-
-    FT_UNUSED( post_len );
+    FT_UShort   n;
+    FT_UShort*  glyph_indices = NULL;
+    FT_Byte*    q;
 
 
-    if ( FT_READ_USHORT( num_glyphs ) )
-      goto Exit;
-
-    /* check the number of glyphs */
-    if ( num_glyphs > face->max_profile.numGlyphs ||
-         num_glyphs > 258                         ||
-         num_glyphs < 1                           )
+    /* check the number of glyphs, including the theoretical limit */
+    if ( num_glyphs > post_len  ||
+         num_glyphs > 258 + 128 )
     {
       error = FT_THROW( Invalid_File_Format );
       goto Exit;
     }
 
-    if ( FT_QNEW_ARRAY( offset_table, num_glyphs )  ||
-         FT_STREAM_READ( offset_table, num_glyphs ) )
+    /* load the indices and check their Mac range */
+    if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) ||
+         FT_FRAME_ENTER( num_glyphs )               )
       goto Fail;
 
-    /* now check the offset table */
+    q = (FT_Byte*)stream->cursor;
+
+    for ( n = 0; n < num_glyphs; n++ )
     {
-      FT_Int  n;
+      FT_Int  idx = n + FT_NEXT_CHAR( q );
 
 
-      for ( n = 0; n < num_glyphs; n++ )
-      {
-        FT_Long  idx = (FT_Long)n + offset_table[n];
+      if ( idx < 0 || idx > 257 )
+        idx = 0;
 
-
-        if ( idx < 0 || idx > num_glyphs )
-        {
-          error = FT_THROW( Invalid_File_Format );
-          goto Fail;
-        }
-      }
+      glyph_indices[n] = (FT_UShort)idx;
     }
 
+    FT_FRAME_EXIT();
+
     /* OK, set table fields and exit successfully */
-    {
-      TT_Post_25  table = &face->postscript_names.names.format_25;
-
-
-      table->num_glyphs = (FT_UShort)num_glyphs;
-      table->offsets    = offset_table;
-    }
+    names->num_glyphs    = num_glyphs;
+    names->glyph_indices = glyph_indices;
 
     return FT_Err_Ok;
 
   Fail:
-    FT_FREE( offset_table );
+    FT_FREE( glyph_indices );
 
   Exit:
     return error;
@@ -370,37 +323,37 @@
   static FT_Error
   load_post_names( TT_Face  face )
   {
-    FT_Stream  stream;
-    FT_Error   error;
-    FT_Fixed   format;
+    FT_Error   error = FT_Err_Ok;
+    FT_Stream  stream = face->root.stream;
+    FT_Fixed   format = face->postscript.FormatType;
     FT_ULong   post_len;
+    FT_UShort  num_glyphs;
 
 
-    /* get a stream for the face's resource */
-    stream = face->root.stream;
-
     /* seek to the beginning of the PS names table */
     error = face->goto_table( face, TTAG_post, stream, &post_len );
     if ( error )
       goto Exit;
 
-    format = face->postscript.FormatType;
-
-    /* go to beginning of subtable */
-    if ( FT_STREAM_SKIP( 32 ) )
+    /* UNDOCUMENTED!  The number of glyphs in this table can be smaller */
+    /* than the value in the maxp table (cf. cyberbit.ttf).             */
+    if ( post_len < 34                            ||
+         FT_STREAM_SKIP( 32 )                     ||
+         FT_READ_USHORT( num_glyphs )             ||
+         num_glyphs > face->max_profile.numGlyphs ||
+         num_glyphs == 0 )
       goto Exit;
 
-    /* now read postscript table */
-    if ( format == 0x00020000L && post_len >= 34 )
-      error = load_format_20( face, stream, post_len - 32 );
-    else if ( format == 0x00025000L && post_len >= 34 )
-      error = load_format_25( face, stream, post_len - 32 );
-    else
-      error = FT_THROW( Invalid_File_Format );
-
-    face->postscript_names.loaded = 1;
+    /* now read postscript names data */
+    if ( format == 0x00020000L )
+      error = load_format_20( &face->postscript_names, stream,
+                              num_glyphs, post_len - 34 );
+    else if ( format == 0x00025000L )
+      error = load_format_25( &face->postscript_names, stream,
+                              num_glyphs, post_len - 34 );
 
   Exit:
+    face->postscript_names.loaded = 1;  /* even if failed */
     return error;
   }
 
@@ -410,39 +363,20 @@
   {
     FT_Memory      memory = face->root.memory;
     TT_Post_Names  names  = &face->postscript_names;
-    FT_Fixed       format;
 
 
-    if ( names->loaded )
+    if ( names->num_glyphs )
     {
-      format = face->postscript.FormatType;
-
-      if ( format == 0x00020000L )
-      {
-        TT_Post_20  table = &names->names.format_20;
-
-
-        FT_FREE( table->glyph_indices );
-        table->num_glyphs = 0;
-
-        if ( table->num_names )
-        {
-          table->glyph_names[0]--;
-          FT_FREE( table->glyph_names[0] );
-
-          FT_FREE( table->glyph_names );
-          table->num_names = 0;
-        }
-      }
-      else if ( format == 0x00025000L )
-      {
-        TT_Post_25  table = &names->names.format_25;
-
-
-        FT_FREE( table->offsets );
-        table->num_glyphs = 0;
-      }
+      FT_FREE( names->glyph_indices );
+      names->num_glyphs = 0;
     }
+
+    if ( names->num_names )
+    {
+      FT_FREE( names->glyph_names );
+      names->num_names = 0;
+    }
+
     names->loaded = 0;
   }
 
@@ -478,7 +412,6 @@
                        FT_String**  PSname )
   {
     FT_Error       error;
-    TT_Post_Names  names;
     FT_Fixed       format;
 
 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
@@ -498,8 +431,6 @@
       return FT_THROW( Unimplemented_Feature );
 #endif
 
-    names = &face->postscript_names;
-
     /* `.notdef' by default */
     *PSname = MAC_NAME( 0 );
 
@@ -510,9 +441,10 @@
       if ( idx < 258 )                    /* paranoid checking */
         *PSname = MAC_NAME( idx );
     }
-    else if ( format == 0x00020000L )
+    else if ( format == 0x00020000L ||
+              format == 0x00025000L )
     {
-      TT_Post_20  table = &names->names.format_20;
+      TT_Post_Names  names = &face->postscript_names;
 
 
       if ( !names->loaded )
@@ -522,43 +454,29 @@
           goto End;
       }
 
-      if ( idx < (FT_UInt)table->num_glyphs )
+      if ( idx < (FT_UInt)names->num_glyphs )
       {
-        FT_UShort  name_index = table->glyph_indices[idx];
+        FT_UShort  name_index = names->glyph_indices[idx];
 
 
         if ( name_index < 258 )
           *PSname = MAC_NAME( name_index );
-        else
-          *PSname = (FT_String*)table->glyph_names[name_index - 258];
+        else  /* only for version 2.0 */
+          *PSname = (FT_String*)names->glyph_names[name_index - 258];
       }
     }
-    else if ( format == 0x00025000L )
-    {
-      TT_Post_25  table = &names->names.format_25;
-
-
-      if ( !names->loaded )
-      {
-        error = load_post_names( face );
-        if ( error )
-          goto End;
-      }
-
-      if ( idx < (FT_UInt)table->num_glyphs )    /* paranoid checking */
-        *PSname = MAC_NAME( (FT_Int)idx + table->offsets[idx] );
-    }
 
     /* nothing to do for format == 0x00030000L */
 
   End:
+    /* post format errors ignored */
     return FT_Err_Ok;
   }
 
 #else /* !TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _tt_post_dummy;
+  typedef int  tt_post_dummy_;
 
 #endif /* !TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
 
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index 3c06955..03f90a6 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -1677,7 +1677,7 @@
 #else /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _tt_sbit_dummy;
+  typedef int  tt_sbit_dummy_;
 
 #endif /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
diff --git a/src/sfnt/ttsvg.c b/src/sfnt/ttsvg.c
index c1bbb66..4461d48 100644
--- a/src/sfnt/ttsvg.c
+++ b/src/sfnt/ttsvg.c
@@ -405,7 +405,7 @@
 #else /* !FT_CONFIG_OPTION_SVG */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _tt_svg_dummy;
+  typedef int  tt_svg_dummy_;
 
 #endif /* !FT_CONFIG_OPTION_SVG */
 
diff --git a/src/sfnt/woff2tags.c b/src/sfnt/woff2tags.c
index 7a0a351..eeedd99 100644
--- a/src/sfnt/woff2tags.c
+++ b/src/sfnt/woff2tags.c
@@ -111,7 +111,7 @@
 #else /* !FT_CONFIG_OPTION_USE_BROTLI */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _woff2tags_dummy;
+  typedef int  woff2tags_dummy_;
 
 #endif /* !FT_CONFIG_OPTION_USE_BROTLI */
 
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index d9f20ee..0918272 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -1006,10 +1006,11 @@
    *
    * For other cases, using binary splits is actually slightly faster.
    */
-#if defined( __SSE2__ )                          || \
-    defined( __x86_64__ )                        || \
-    defined( _M_AMD64 )                          || \
-    ( defined( _M_IX86_FP ) && _M_IX86_FP >= 2 )
+#if ( defined( __SSE2__ )                          ||   \
+      defined( __x86_64__ )                        ||   \
+      defined( _M_AMD64 )                          ||   \
+      ( defined( _M_IX86_FP ) && _M_IX86_FP >= 2 ) ) && \
+    !defined( __VMS )
 #  define FT_SSE2 1
 #else
 #  define FT_SSE2 0
@@ -1427,8 +1428,10 @@
 
   static int
   gray_move_to( const FT_Vector*  to,
-                gray_PWorker      worker )
+                void*             worker_ )  /* gray_PWorker */
   {
+    gray_PWorker  worker = (gray_PWorker)worker_;
+
     TPos  x, y;
 
 
@@ -1446,8 +1449,11 @@
 
   static int
   gray_line_to( const FT_Vector*  to,
-                gray_PWorker      worker )
+                void*             worker_ )   /* gray_PWorker */
   {
+    gray_PWorker  worker = (gray_PWorker)worker_;
+
+
     gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) );
     return 0;
   }
@@ -1456,8 +1462,11 @@
   static int
   gray_conic_to( const FT_Vector*  control,
                  const FT_Vector*  to,
-                 gray_PWorker      worker )
+                 void*             worker_ )   /* gray_PWorker */
   {
+    gray_PWorker  worker = (gray_PWorker)worker_;
+
+
     gray_render_conic( RAS_VAR_ control, to );
     return 0;
   }
@@ -1467,8 +1476,11 @@
   gray_cubic_to( const FT_Vector*  control1,
                  const FT_Vector*  control2,
                  const FT_Vector*  to,
-                 gray_PWorker      worker )
+                 void*             worker_ )   /* gray_PWorker */
   {
+    gray_PWorker  worker = (gray_PWorker)worker_;
+
+
     gray_render_cubic( RAS_VAR_ control1, control2, to );
     return 0;
   }
@@ -1666,6 +1678,8 @@
 
     int   n;         /* index of contour in outline     */
     int   first;     /* index of first point in contour */
+    int   last;      /* index of last point in contour  */
+
     char  tag;       /* current point's state           */
 
     int   shift;
@@ -1680,18 +1694,17 @@
 
     shift = func_interface->shift;
     delta = func_interface->delta;
-    first = 0;
 
+    last = -1;
     for ( n = 0; n < outline->n_contours; n++ )
     {
-      int  last;  /* index of last point in contour */
+      FT_TRACE5(( "FT_Outline_Decompose: Contour %d\n", n ));
 
-
-      FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n ));
-
+      first = last + 1;
       last  = outline->contours[n];
-      if ( last < 0 )
+      if ( last < first )
         goto Invalid_Outline;
+
       limit = outline->points + last;
 
       v_start   = outline->points[first];
@@ -1874,11 +1887,9 @@
                   v_start.x / 64.0, v_start.y / 64.0 ));
       error = func_interface->line_to( &v_start, user );
 
-   Close:
+    Close:
       if ( error )
         goto Exit;
-
-      first = last + 1;
     }
 
     FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
@@ -1923,7 +1934,7 @@
       if ( continued )
         FT_Trace_Enable();
 
-      FT_TRACE7(( "band [%d..%d]: %ld cell%s remaining/\n",
+      FT_TRACE7(( "band [%d..%d]: %td cell%s remaining/\n",
                   ras.min_ey,
                   ras.max_ey,
                   ras.cell_null - ras.cell_free,
@@ -2156,9 +2167,12 @@
 #else /* !STANDALONE_ */
 
   static int
-  gray_raster_new( FT_Memory      memory,
-                   gray_PRaster*  araster )
+  gray_raster_new( void*       memory_,
+                   FT_Raster*  araster_ )
   {
+    FT_Memory      memory  = (FT_Memory)memory_;
+    gray_PRaster*  araster = (gray_PRaster*)araster_;
+
     FT_Error      error;
     gray_PRaster  raster = NULL;
 
diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c
index cdbc78c..9b0e888 100644
--- a/src/smooth/ftsmooth.c
+++ b/src/smooth/ftsmooth.c
@@ -87,8 +87,10 @@
 
   /* initialize renderer -- init its raster */
   static FT_Error
-  ft_smooth_init( FT_Renderer  render )
+  ft_smooth_init( FT_Module  module )   /* FT_Renderer */
   {
+    FT_Renderer  render = (FT_Renderer)module;
+
     FT_Vector*  sub = render->root.library->lcd_geometry;
 
 
@@ -111,8 +113,10 @@
   ft_smooth_lcd_spans( int             y,
                        int             count,
                        const FT_Span*  spans,
-                       TOrigin*        target )
+                       void*           target_ )   /* TOrigin* */
   {
+    TOrigin*  target = (TOrigin*)target_;
+
     unsigned char*  dst_line = target->origin - y * target->pitch;
     unsigned char*  dst;
     unsigned short  w;
@@ -141,7 +145,7 @@
     /* Set up direct rendering to record them on each third byte. */
     params.source     = outline;
     params.flags      = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT;
-    params.gray_spans = (FT_SpanFunc)ft_smooth_lcd_spans;
+    params.gray_spans = ft_smooth_lcd_spans;
     params.user       = &target;
 
     params.clip_box.xMin = 0;
@@ -256,8 +260,11 @@
 
   /* initialize renderer -- init its raster */
   static FT_Error
-  ft_smooth_init( FT_Renderer  render )
+  ft_smooth_init( FT_Module  module )   /* FT_Renderer */
   {
+    FT_Renderer  render = (FT_Renderer)module;
+
+
     /* set up default LCD filtering */
     FT_Library_SetLcdFilter( render->root.library, FT_LCD_FILTER_DEFAULT );
 
@@ -340,8 +347,11 @@
   ft_smooth_overlap_spans( int             y,
                            int             count,
                            const FT_Span*  spans,
-                           TOrigin*        target )
+                           void*           target_ )
   {
+    TOrigin*  target = (TOrigin*)target_;
+
+
     unsigned char*  dst = target->origin - ( y / SCALE ) * target->pitch;
     unsigned short  x;
     unsigned int    cover, sum;
@@ -386,7 +396,7 @@
     /* Set up direct rendering to average oversampled spans. */
     params.source     = outline;
     params.flags      = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT;
-    params.gray_spans = (FT_SpanFunc)ft_smooth_overlap_spans;
+    params.gray_spans = ft_smooth_overlap_spans;
     params.user       = &target;
 
     params.clip_box.xMin = 0;
diff --git a/src/svg/ftsvg.c b/src/svg/ftsvg.c
index 7edb1a3..ba237f6 100644
--- a/src/svg/ftsvg.c
+++ b/src/svg/ftsvg.c
@@ -40,26 +40,31 @@
 
   /* ft_svg_init */
   static FT_Error
-  ft_svg_init( SVG_Renderer  svg_module )
+  ft_svg_init( FT_Module  module )
   {
+    SVG_Renderer  render = (SVG_Renderer)module;
+
     FT_Error  error = FT_Err_Ok;
 
 
-    svg_module->loaded    = FALSE;
-    svg_module->hooks_set = FALSE;
+    render->loaded    = FALSE;
+    render->hooks_set = FALSE;
 
     return error;
   }
 
 
   static void
-  ft_svg_done( SVG_Renderer  svg_module )
+  ft_svg_done( FT_Module  module )
   {
-    if ( svg_module->loaded    == TRUE &&
-         svg_module->hooks_set == TRUE )
-      svg_module->hooks.free_svg( &svg_module->state );
+    SVG_Renderer  render = (SVG_Renderer)module;
 
-    svg_module->loaded = FALSE;
+
+    if ( render->loaded    == TRUE &&
+         render->hooks_set == TRUE )
+      render->hooks.free_svg( &render->state );
+
+    render->loaded = FALSE;
   }
 
 
@@ -148,7 +153,7 @@
 
   static const SVG_Interface  svg_interface =
   {
-    (Preset_Bitmap_Func)ft_svg_preset_slot
+    ft_svg_preset_slot  /* Preset_Bitmap_Func preset_slot */
   };
 
 
@@ -203,7 +208,7 @@
   static FT_Error
   ft_svg_property_get( FT_Module    module,
                        const char*  property_name,
-                       const void*  value )
+                       void*        value )
   {
     FT_Error      error    = FT_Err_Ok;
     SVG_Renderer  renderer = (SVG_Renderer)module;
@@ -226,8 +231,8 @@
   FT_DEFINE_SERVICE_PROPERTIESREC(
     ft_svg_service_properties,
 
-    (FT_Properties_SetFunc)ft_svg_property_set, /* set_property */
-    (FT_Properties_GetFunc)ft_svg_property_get  /* get_property */
+    ft_svg_property_set,  /* FT_Properties_SetFunc set_property */
+    ft_svg_property_get   /* FT_Properties_GetFunc get_property */
   )
 
 
@@ -333,17 +338,17 @@
 
       (const void*)PUT_SVG_MODULE( &svg_interface ), /* module specific interface */
 
-      (FT_Module_Constructor)PUT_SVG_MODULE( ft_svg_init ), /* module_init   */
-      (FT_Module_Destructor)PUT_SVG_MODULE( ft_svg_done ),  /* module_done   */
-      PUT_SVG_MODULE( ft_svg_get_interface ),               /* get_interface */
+      PUT_SVG_MODULE( ft_svg_init ),           /* FT_Module_Constructor module_init   */
+      PUT_SVG_MODULE( ft_svg_done ),           /* FT_Module_Destructor  module_done   */
+      PUT_SVG_MODULE( ft_svg_get_interface ),  /* FT_Module_Requester   get_interface */
 
       SVG_GLYPH_FORMAT,
 
-      (FT_Renderer_RenderFunc)   PUT_SVG_MODULE( ft_svg_render ),    /* render_glyph    */
-      (FT_Renderer_TransformFunc)PUT_SVG_MODULE( ft_svg_transform ), /* transform_glyph */
-      NULL,                                                          /* get_glyph_cbox  */
-      NULL,                                                          /* set_mode        */
-      NULL                                                           /* raster_class    */
+      PUT_SVG_MODULE( ft_svg_render ),     /* FT_Renderer_RenderFunc    render_glyph    */
+      PUT_SVG_MODULE( ft_svg_transform ),  /* FT_Renderer_TransformFunc transform_glyph */
+      NULL,                                /* FT_Renderer_GetCBoxFunc   get_glyph_cbox  */
+      NULL,                                /* FT_Renderer_SetModeFunc   set_mode        */
+      NULL                                 /* FT_Raster_Funcs*          raster_class    */
   )
 
 
diff --git a/src/tools/apinames.c b/src/tools/apinames.c
index 8a8b082..dfa258f 100644
--- a/src/tools/apinames.c
+++ b/src/tools/apinames.c
@@ -18,11 +18,14 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <string.h>
 #include <ctype.h>
 
+#include "vms_shorten_symbol.c"
+
 #define  PROGRAM_NAME     "apinames"
-#define  PROGRAM_VERSION  "0.4"
+#define  PROGRAM_VERSION  "0.5"
 
 #define  LINEBUFF_SIZE  1024
 
@@ -41,9 +44,20 @@
 
 
 static void
-panic( const char*  message )
+panic( const char*  fmt,
+       ... )
 {
-  fprintf( stderr, "PANIC: %s\n", message );
+  va_list  ap;
+
+
+  fprintf( stderr, "PANIC: " );
+
+  va_start( ap, fmt );
+  vfprintf( stderr, fmt, ap );
+  va_end( ap );
+
+  fprintf( stderr, "\n" );
+
   exit(2);
 }
 
@@ -202,12 +216,24 @@
     break;
 
   case OUTPUT_VMS_OPT:
-    fprintf( out, "GSMATCH=LEQUAL,2,0\n"
-                  "CASE_SENSITIVE=YES\n"
-                  "SYMBOL_VECTOR=(-\n" );
-    for ( nn = 0; nn < num_names - 1; nn++ )
-      fprintf( out, "    %s=PROCEDURE,-\n", the_names[nn].name );
-    fprintf( out, "    %s=PROCEDURE)\n", the_names[num_names - 1].name );
+    fprintf( out, "case_sensitive=YES\n" );
+
+    for ( nn = 0; nn < num_names; nn++ )
+    {
+      char  short_symbol[32];
+
+
+      if ( vms_shorten_symbol( the_names[nn].name, short_symbol, 1 ) == -1 )
+        panic( "could not shorten name '%s'", the_names[nn].name );
+      fprintf( out, "symbol_vector = ( %s = PROCEDURE)\n", short_symbol );
+
+      /* Also emit a 64-bit symbol, as created by the `vms_auto64` tool. */
+      /* It has the string '64__' appended to its name.                  */
+      strcat( the_names[nn].name , "64__" );
+      if ( vms_shorten_symbol( the_names[nn].name, short_symbol, 1 ) == -1 )
+        panic( "could not shorten name '%s'", the_names[nn].name );
+      fprintf( out, "symbol_vector = ( %s = PROCEDURE)\n", short_symbol );
+    }
 
     break;
 
diff --git a/src/tools/ftrandom/ftrandom.c b/src/tools/ftrandom/ftrandom.c
index 4f912cd..0ee765e 100644
--- a/src/tools/ftrandom/ftrandom.c
+++ b/src/tools/ftrandom/ftrandom.c
@@ -520,7 +520,7 @@
     char        buffer[1024];
 
 
-    sprintf( buffer, "%s/test%d", results_dir, test_num++ );
+    snprintf( buffer, 1024, "%s/test%d", results_dir, test_num++ );
 
     if ( copyfont ( &fontlist[i], buffer ) )
     {
diff --git a/src/tools/vms_shorten_symbol.c b/src/tools/vms_shorten_symbol.c
new file mode 100644
index 0000000..81f2a71
--- /dev/null
+++ b/src/tools/vms_shorten_symbol.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2010, 2017 Craig A. Berry
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* vms_shorten_symbol
+ * 
+ * This program provides shortening of long symbols (> 31 characters) using the
+ * same mechanism as the OpenVMS C compiler.  The basic procedure is to compute
+ * an AUTODIN II checksum of the entire symbol, encode the checksum in base32,
+ * and glue together a shortened symbol from the first 23 characters of the 
+ * original symbol plus the encoded checksum appended.  The output format is
+ * the same used in the name mangler database, stored by default in 
+ * [.CXX_REPOSITORY]CXX$DEMANGLER_DB.
+ *
+ * To obtain the same result as CC/NAMES=SHORTENED, run like so:
+ * 
+ * $ mcr []vms_shorten_symbol "Please_forgive_this_absurdly_long_symbol_name"
+ * PLEASE_FORGIVE_THIS_ABS1ARO4QU$Please_forgive_this_absurdly_long_symbol_name
+ *
+ * To obtain the same result as CC/NAMES=(SHORTENED,AS_IS), pass a non-zero
+ * value as the second argument, like so:
+ *
+ * $ mcr []vms_shorten_symbol "Please_forgive_this_absurdly_long_symbol_name" 1
+ * Please_forgive_this_abs3rv8rnn$Please_forgive_this_absurdly_long_symbol_name
+ */
+ 
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __VMS
+#define UINT32 unsigned int
+#else
+#include <inttypes.h>
+#define UINT32 uint32_t
+#endif
+
+extern UINT32 crc32(const char *input_string);
+extern int u32_to_base32(UINT32 input, char *output);
+extern int vms_shorten_symbol(const char *symbol, char *shortened, char as_is_flag);
+
+/*
+ * This routine implements the AUTODIN II polynomial.
+ */
+
+UINT32
+crc32(const char *input_string)
+{
+
+/*
+ * CRC code and data based partly on FreeBSD implementation, which
+ * notes:
+ *
+ * The crc32 functions and data was originally written by Spencer
+ * Garrett <srg@quick.com> and was cleaned from the PostgreSQL source
+ * tree via the files contrib/ltree/crc32.[ch].  No license was
+ * included, therefore it is assumed that this code is public
+ * domain.  Attribution still noted.
+ *
+ * (I think they mean "gleaned" not "cleaned".)
+ */
+
+    static const UINT32 autodin_ii_table[256] = {
+        0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+        0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+        0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+        0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+        0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+        0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+        0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+        0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+        0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+        0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+        0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+        0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+        0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+        0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+        0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+        0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+        0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+        0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+        0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+        0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+        0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+        0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+        0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+        0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+        0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+        0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+        0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+        0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+        0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+        0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+        0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+        0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+        0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+        0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+        0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+        0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+        0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+        0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+        0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+        0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+        0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+        0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+        0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
+    };
+    
+    UINT32 crc = ~0U;
+    char *c;
+    for (c = (char *)input_string; *c; ++c)
+        crc = (crc >> 8) ^ autodin_ii_table[(crc ^ *c) & 0xff];
+    return ~crc;
+}
+
+/*
+ * This is the RFC2938 variant of base32, not RFC3548, Crockford's, or
+ * other newer variant.  It produces an 8-byte encoded character string
+ * (plus trailing null) from a 32-bit integer input.
+ */
+
+int
+u32_to_base32(UINT32 input, char *output)
+{
+    static const char base32hex_table[32] = {
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+        'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+        'u', 'v'
+    };
+    int i;
+
+    /* 
+     * Grab lowest 5 bits and look up conversion in table.  Lather, rinse,
+     * repeat for a total of 7, 5-bit chunks to accommodate 32 bits of input.
+     */
+    for (i = 0; i < 7; i++) {
+        output[6 - i] = base32hex_table[input & 0x1f];
+        input >>= 5;     /* position to look at next 5 */
+    }
+    output[7] = '$';     /* It's DEC, so use '$' not '=' to pad. */
+    output[8] = '\0';    
+    return 0;    
+}
+
+/*
+ * Take an input symbol name of arbitrary length and produce a symbol shortened
+ * to 31 characters.  The shortened symbol consists of the first 23 characters
+ * of the original symbol plus the 8 characters of the encoded checksum.  The
+ * third argument is a boolean indicating whether to emulate the compiler's
+ * /NAMES=AS_IS option.  When false (the compiler's default), the shortened
+ * symbol will be upper cased.  When the original symbol is 31 characters or 
+ * fewer in length, no checksum will be appended and the original symbol is
+ * returned verbatim (though upper cased if the as_is_flag is false).
+ */
+
+int
+vms_shorten_symbol(const char *input_symbol, char *shortened, char as_is_flag)
+{
+    char b32str[9];
+    UINT32 crc;
+    char *c, *symbol;
+    int symlen;
+
+    symlen = strlen(input_symbol);
+    symbol = (char *)malloc(symlen + 1);
+    if (symbol == NULL)
+        return -1;
+
+    strncpy(symbol, input_symbol, symlen);
+    symbol[symlen] = '\0';
+
+    if (!as_is_flag) {
+        for (c = symbol; *c; c++)
+            *c = toupper(*c);
+    }
+
+    if (symlen <= 31) {
+        strncpy(shortened, symbol, symlen);
+        shortened[symlen] = '\0';
+        free(symbol);
+        return 0;
+    }
+        
+    /*
+     * Compute the checksum on the whole symbol.
+     */
+
+    crc = crc32(symbol);
+
+    /* The compiler does not use the inverted checksum, so we invert it
+     * back before encoding in base32.
+     */
+
+    if (u32_to_base32(~crc, (char *)&b32str) == -1) {
+        free(symbol);
+        return -1;
+    }
+
+    if (!as_is_flag) {
+        for (c = (char *)&b32str; *c; c++)
+            *c = toupper(*c);
+    }
+
+    sprintf(shortened, "%.23s%.8s", symbol, b32str);
+    shortened[31] = '\0';
+    free(symbol);
+    return 0;
+}
+
+#ifdef TEST_MAIN
+int
+main(int argc, char **argv)
+{
+    char short_symbol[32];
+    char as_is_flag = 0;
+
+    if (argc < 2) {
+        fprintf(stderr, "Usage: %s <symbol name> [<AS_IS flag>]\n", argv[0]);
+        exit(EXIT_FAILURE);
+    }
+    if (argc > 2)
+        as_is_flag = 1;
+
+    if (vms_shorten_symbol(argv[1], (char *)&short_symbol, as_is_flag) == -1) {
+        fprintf(stderr, "Symbol shortening failed\n");
+        exit(EXIT_FAILURE);
+    }
+
+    printf("%s%s\n", (char *)&short_symbol, argv[1]);
+}
+#endif
diff --git a/src/truetype/rules.mk b/src/truetype/rules.mk
index 23f6f00..dde26de 100644
--- a/src/truetype/rules.mk
+++ b/src/truetype/rules.mk
@@ -33,8 +33,7 @@
               $(TT_DIR)/ttgxvar.c  \
               $(TT_DIR)/ttinterp.c \
               $(TT_DIR)/ttobjs.c   \
-              $(TT_DIR)/ttpload.c  \
-              $(TT_DIR)/ttsubpix.c
+              $(TT_DIR)/ttpload.c
 
 # TrueType driver headers
 #
diff --git a/src/truetype/truetype.c b/src/truetype/truetype.c
index c5faa96..fcc0ea3 100644
--- a/src/truetype/truetype.c
+++ b/src/truetype/truetype.c
@@ -24,7 +24,6 @@
 #include "ttinterp.c"
 #include "ttobjs.c"     /* object manager      */
 #include "ttpload.c"    /* tables loader       */
-#include "ttsubpix.c"
 
 
 /* END */
diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c
index 813b52b..d1496fe 100644
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -57,7 +57,7 @@
    * PROPERTY SERVICE
    *
    */
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   tt_property_set( FT_Module    module,         /* TT_Driver */
                    const char*  property_name,
                    const void*  value,
@@ -93,17 +93,22 @@
         interpreter_version = *iv;
       }
 
-      if ( interpreter_version == TT_INTERPRETER_VERSION_35
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-           || interpreter_version == TT_INTERPRETER_VERSION_38
-#endif
+      switch ( interpreter_version )
+      {
+      case TT_INTERPRETER_VERSION_35:
+        driver->interpreter_version = TT_INTERPRETER_VERSION_35;
+        break;
+
+      case TT_INTERPRETER_VERSION_38:
+      case TT_INTERPRETER_VERSION_40:
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-           || interpreter_version == TT_INTERPRETER_VERSION_40
+        driver->interpreter_version = TT_INTERPRETER_VERSION_40;
+      break;
 #endif
-         )
-        driver->interpreter_version = interpreter_version;
-      else
+
+      default:
         error = FT_ERR( Unimplemented_Feature );
+      }
 
       return error;
     }
@@ -114,10 +119,10 @@
   }
 
 
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   tt_property_get( FT_Module    module,         /* TT_Driver */
                    const char*  property_name,
-                   const void*  value )
+                   void*        value )
   {
     FT_Error   error  = FT_Err_Ok;
     TT_Driver  driver = (TT_Driver)module;
@@ -144,8 +149,8 @@
   FT_DEFINE_SERVICE_PROPERTIESREC(
     tt_service_properties,
 
-    (FT_Properties_SetFunc)tt_property_set,     /* set_property */
-    (FT_Properties_GetFunc)tt_property_get      /* get_property */
+    tt_property_set,  /* FT_Properties_SetFunc set_property */
+    tt_property_get   /* FT_Properties_GetFunc get_property */
   )
 
 
@@ -198,35 +203,35 @@
    *
    *   They can be implemented by format-specific interfaces.
    */
-  static FT_Error
-  tt_get_kerning( FT_Face     ttface,          /* TT_Face */
+  FT_CALLBACK_DEF( FT_Error )
+  tt_get_kerning( FT_Face     face,        /* TT_Face */
                   FT_UInt     left_glyph,
                   FT_UInt     right_glyph,
                   FT_Vector*  kerning )
   {
-    TT_Face       face = (TT_Face)ttface;
-    SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
+    TT_Face       ttface = (TT_Face)face;
+    SFNT_Service  sfnt   = (SFNT_Service)ttface->sfnt;
 
 
     kerning->x = 0;
     kerning->y = 0;
 
     if ( sfnt )
-      kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
+      kerning->x = sfnt->get_kerning( ttface, left_glyph, right_glyph );
 
     return 0;
   }
 
 
-  static FT_Error
-  tt_get_advances( FT_Face    ttface,
+  FT_CALLBACK_DEF( FT_Error )
+  tt_get_advances( FT_Face    face,      /* TT_Face */
                    FT_UInt    start,
                    FT_UInt    count,
                    FT_Int32   flags,
                    FT_Fixed  *advances )
   {
     FT_UInt  nn;
-    TT_Face  face = (TT_Face)ttface;
+    TT_Face  ttface = (TT_Face)face;
 
 
     /* XXX: TODO: check for sbits */
@@ -235,8 +240,8 @@
     {
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
       /* no fast retrieval for blended MM fonts without VVAR table */
-      if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) &&
-           !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE )        )
+      if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
+           !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE )  )
         return FT_THROW( Unimplemented_Feature );
 #endif
 
@@ -247,7 +252,7 @@
 
 
         /* since we don't need `tsb', we use zero for `yMax' parameter */
-        TT_Get_VMetrics( face, start + nn, 0, &tsb, &ah );
+        TT_Get_VMetrics( ttface, start + nn, 0, &tsb, &ah );
         advances[nn] = ah;
       }
     }
@@ -255,8 +260,8 @@
     {
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
       /* no fast retrieval for blended MM fonts without HVAR table */
-      if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) &&
-           !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE )        )
+      if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
+           !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE )  )
         return FT_THROW( Unimplemented_Feature );
 #endif
 
@@ -266,7 +271,7 @@
         FT_UShort  aw;
 
 
-        TT_Get_HMetrics( face, start + nn, &lsb, &aw );
+        TT_Get_HMetrics( ttface, start + nn, &lsb, &aw );
         advances[nn] = aw;
       }
     }
@@ -290,7 +295,7 @@
 
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   tt_size_select( FT_Size   size,
                   FT_ULong  strike_index )
   {
@@ -327,7 +332,7 @@
 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
 
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   tt_size_request( FT_Size          size,
                    FT_Size_Request  req )
   {
@@ -426,15 +431,15 @@
    * @Return:
    *   FreeType error code.  0 means success.
    */
-  static FT_Error
-  tt_glyph_load( FT_GlyphSlot  ttslot,      /* TT_GlyphSlot */
-                 FT_Size       ttsize,      /* TT_Size      */
+  FT_CALLBACK_DEF( FT_Error )
+  tt_glyph_load( FT_GlyphSlot  slot,        /* TT_GlyphSlot */
+                 FT_Size       size,        /* TT_Size      */
                  FT_UInt       glyph_index,
                  FT_Int32      load_flags )
   {
-    TT_GlyphSlot  slot = (TT_GlyphSlot)ttslot;
-    TT_Size       size = (TT_Size)ttsize;
-    FT_Face       face = ttslot->face;
+    TT_GlyphSlot  ttslot = (TT_GlyphSlot)slot;
+    TT_Size       ttsize = (TT_Size)size;
+    FT_Face       face   = ttslot->face;
     FT_Error      error;
 
 
@@ -476,12 +481,12 @@
     }
 
     /* use hinted metrics only if we load a glyph with hinting */
-    size->metrics = ( load_flags & FT_LOAD_NO_HINTING )
-                      ? &ttsize->metrics
-                      : &size->hinted_metrics;
+    ttsize->metrics = ( load_flags & FT_LOAD_NO_HINTING )
+                        ? &size->metrics
+                        : &ttsize->hinted_metrics;
 
     /* now fill in the glyph slot with outline/bitmap/layered */
-    error = TT_Load_Glyph( size, slot, glyph_index, load_flags );
+    error = TT_Load_Glyph( ttsize, ttslot, glyph_index, load_flags );
 
     /* force drop-out mode to 2 - irrelevant now */
     /* slot->outline.dropout_mode = 2; */
@@ -507,50 +512,47 @@
   FT_DEFINE_SERVICE_MULTIMASTERSREC(
     tt_service_gx_multi_masters,
 
-    (FT_Get_MM_Func)        NULL,                  /* get_mm                    */
-    (FT_Set_MM_Design_Func) NULL,                  /* set_mm_design             */
-    (FT_Set_MM_Blend_Func)  TT_Set_MM_Blend,       /* set_mm_blend              */
-    (FT_Get_MM_Blend_Func)  TT_Get_MM_Blend,       /* get_mm_blend              */
-    (FT_Get_MM_Var_Func)    TT_Get_MM_Var,         /* get_mm_var                */
-    (FT_Set_Var_Design_Func)TT_Set_Var_Design,     /* set_var_design            */
-    (FT_Get_Var_Design_Func)TT_Get_Var_Design,     /* get_var_design            */
-    (FT_Set_Instance_Func)  TT_Set_Named_Instance, /* set_instance              */
-    (FT_Set_MM_WeightVector_Func)
-                            NULL,                  /* set_mm_weightvector       */
-    (FT_Get_MM_WeightVector_Func)
-                            NULL,                  /* get_mm_weightvector       */
-    (FT_Var_Load_Delta_Set_Idx_Map_Func)
-                            tt_var_load_delta_set_index_mapping,
-                                                   /* load_delta_set_idx_map    */
-    (FT_Var_Load_Item_Var_Store_Func)
-                            tt_var_load_item_variation_store,
-                                                   /* load_item_variation_store */
-    (FT_Var_Get_Item_Delta_Func)
-                            tt_var_get_item_delta, /* get_item_delta            */
-    (FT_Var_Done_Item_Var_Store_Func)
-                            tt_var_done_item_variation_store,
-                                                   /* done_item_variation_store */
-    (FT_Var_Done_Delta_Set_Idx_Map_Func)
-                            tt_var_done_delta_set_index_map,
-                                                   /* done_delta_set_index_map  */
-    (FT_Get_Var_Blend_Func) tt_get_var_blend,      /* get_var_blend             */
-    (FT_Done_Blend_Func)    tt_done_blend          /* done_blend                */
+    NULL,                  /* FT_Get_MM_Func              get_mm                     */
+    NULL,                  /* FT_Set_MM_Design_Func       set_mm_design              */
+    TT_Set_MM_Blend,       /* FT_Set_MM_Blend_Func        set_mm_blend               */
+    TT_Get_MM_Blend,       /* FT_Get_MM_Blend_Func        get_mm_blend               */
+    TT_Get_MM_Var,         /* FT_Get_MM_Var_Func          get_mm_var                 */
+    TT_Set_Var_Design,     /* FT_Set_Var_Design_Func      set_var_design             */
+    TT_Get_Var_Design,     /* FT_Get_Var_Design_Func      get_var_design             */
+    TT_Set_Named_Instance, /* FT_Set_Named_Instance_Func  set_named_instance         */
+    TT_Get_Default_Named_Instance,
+                    /* FT_Get_Default_Named_Instance_Func get_default_named_instance */
+    NULL,                  /* FT_Set_MM_WeightVector_Func set_mm_weightvector        */
+    NULL,                  /* FT_Get_MM_WeightVector_Func get_mm_weightvector        */
+
+    tt_construct_ps_name,  /* FT_Construct_PS_Name_Func   construct_ps_name          */
+    tt_var_load_delta_set_index_mapping,
+                    /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map     */
+    tt_var_load_item_variation_store,
+                    /* FT_Var_Load_Item_Var_Store_Func    load_item_variation_store  */
+    tt_var_get_item_delta, /* FT_Var_Get_Item_Delta_Func  get_item_delta             */
+    tt_var_done_item_variation_store,
+                    /* FT_Var_Done_Item_Var_Store_Func    done_item_variation_store  */
+    tt_var_done_delta_set_index_map,
+                    /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map   */
+    tt_get_var_blend,      /* FT_Get_Var_Blend_Func       get_var_blend              */
+    tt_done_blend          /* FT_Done_Blend_Func          done_blend                 */
   )
 
   FT_DEFINE_SERVICE_METRICSVARIATIONSREC(
     tt_service_metrics_variations,
 
-    (FT_HAdvance_Adjust_Func)tt_hadvance_adjust,     /* hadvance_adjust */
-    (FT_LSB_Adjust_Func)     NULL,                   /* lsb_adjust      */
-    (FT_RSB_Adjust_Func)     NULL,                   /* rsb_adjust      */
+    tt_hadvance_adjust,   /* FT_HAdvance_Adjust_Func hadvance_adjust */
+    NULL,                 /* FT_LSB_Adjust_Func      lsb_adjust      */
+    NULL,                 /* FT_RSB_Adjust_Func      rsb_adjust      */
 
-    (FT_VAdvance_Adjust_Func)tt_vadvance_adjust,     /* vadvance_adjust */
-    (FT_TSB_Adjust_Func)     NULL,                   /* tsb_adjust      */
-    (FT_BSB_Adjust_Func)     NULL,                   /* bsb_adjust      */
-    (FT_VOrg_Adjust_Func)    NULL,                   /* vorg_adjust     */
+    tt_vadvance_adjust,   /* FT_VAdvance_Adjust_Func vadvance_adjust */
+    NULL,                 /* FT_TSB_Adjust_Func      tsb_adjust      */
+    NULL,                 /* FT_BSB_Adjust_Func      bsb_adjust      */
+    NULL,                 /* FT_VOrg_Adjust_Func     vorg_adjust     */
 
-    (FT_Metrics_Adjust_Func) tt_apply_mvar,          /* metrics_adjust  */
-    (FT_Size_Reset_Func)     tt_size_reset_height    /* size_reset      */
+    tt_apply_mvar,        /* FT_Metrics_Adjust_Func  metrics_adjust  */
+    tt_size_reset_height  /* FT_Size_Reset_Func      size_reset      */
   )
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index d33bdad..dc427e8 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -35,7 +35,6 @@
 #endif
 
 #include "tterrors.h"
-#include "ttsubpix.h"
 
 
   /**************************************************************************
@@ -152,9 +151,6 @@
                   FT_UInt    glyph_index )
   {
     TT_Face    face   = loader->face;
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
-#endif
 
     FT_Error   error;
     FT_Stream  stream = loader->stream;
@@ -183,20 +179,6 @@
     loader->top_bearing  = top_bearing;
     loader->vadvance     = advance_height;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
-         loader->exec                                             )
-    {
-      loader->exec->sph_tweak_flags = 0;
-
-      /* 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 */
-      /* backward compatibility mode on and off.                    */
-      sph_set_tweaks( loader, glyph_index );
-    }
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
     /* With the incremental interface, these values are set by  */
     /* a call to `tt_get_metrics_incremental'.                  */
@@ -362,17 +344,16 @@
     FT_Byte*        p          = load->cursor;
     FT_Byte*        limit      = load->limit;
     FT_GlyphLoader  gloader    = load->gloader;
+    FT_Outline*     outline    = &gloader->current.outline;
     FT_Int          n_contours = load->n_contours;
-    FT_Outline*     outline;
-    FT_UShort       n_ins;
     FT_Int          n_points;
+    FT_UShort       n_ins;
 
     FT_Byte         *flag, *flag_limit;
     FT_Byte         c, count;
     FT_Vector       *vec, *vec_limit;
     FT_Pos          x, y;
-    FT_Short        *cont, *cont_limit, prev_cont;
-    FT_Int          xy_size = 0;
+    FT_Short        *cont, *cont_limit, last;
 
 
     /* check that we can add the contours to the glyph */
@@ -380,40 +361,26 @@
     if ( error )
       goto Fail;
 
+    /* check space for contours array + instructions count */
+    if ( n_contours >= 0xFFF || p + 2 * n_contours + 2 > limit )
+      goto Invalid_Outline;
+
     /* reading the contours' endpoints & number of points */
-    cont       = gloader->current.outline.contours;
+    cont       = outline->contours;
     cont_limit = cont + n_contours;
 
-    /* check space for contours array + instructions count */
-    if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit )
-      goto Invalid_Outline;
-
-    prev_cont = FT_NEXT_SHORT( p );
-
-    if ( n_contours > 0 )
-      cont[0] = prev_cont;
-
-    if ( prev_cont < 0 )
-      goto Invalid_Outline;
-
-    for ( cont++; cont < cont_limit; cont++ )
+    last = -1;
+    for ( ; cont < cont_limit; cont++ )
     {
-      cont[0] = FT_NEXT_SHORT( p );
-      if ( cont[0] <= prev_cont )
-      {
-        /* unordered contours: this is invalid */
+      *cont = FT_NEXT_SHORT( p );
+
+      if ( *cont <= last )
         goto Invalid_Outline;
-      }
-      prev_cont = cont[0];
+
+      last = *cont;
     }
 
-    n_points = 0;
-    if ( n_contours > 0 )
-    {
-      n_points = cont[-1] + 1;
-      if ( n_points < 0 )
-        goto Invalid_Outline;
-    }
+    n_points = last + 1;
 
     FT_TRACE5(( "  # of points: %d\n", n_points ));
 
@@ -422,59 +389,48 @@
     if ( error )
       goto Fail;
 
-    /* reading the bytecode instructions */
-    load->glyph->control_len  = 0;
-    load->glyph->control_data = NULL;
-
-    if ( p + 2 > limit )
-      goto Invalid_Outline;
-
+    /* space checked above */
     n_ins = FT_NEXT_USHORT( p );
 
     FT_TRACE5(( "  Instructions size: %u\n", n_ins ));
 
+    /* check instructions size */
+    if ( p + n_ins > limit )
+    {
+      FT_TRACE1(( "TT_Load_Simple_Glyph: excessive instruction count\n" ));
+      error = FT_THROW( Too_Many_Hints );
+      goto Fail;
+    }
+
 #ifdef TT_USE_BYTECODE_INTERPRETER
 
     if ( IS_HINTED( load->load_flags ) )
     {
-      FT_ULong  tmp;
+      TT_ExecContext  exec = load->exec;
+      FT_Memory       memory = exec->memory;
 
 
-      /* check instructions size */
-      if ( ( limit - p ) < n_ins )
-      {
-        FT_TRACE1(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));
-        error = FT_THROW( Too_Many_Hints );
-        goto Fail;
-      }
+      if ( exec->glyphSize )
+        FT_FREE( exec->glyphIns );
+      exec->glyphSize = 0;
 
       /* we don't trust `maxSizeOfInstructions' in the `maxp' table */
-      /* and thus update the bytecode array size by ourselves       */
-
-      tmp   = load->exec->glyphSize;
-      error = Update_Max( load->exec->memory,
-                          &tmp,
-                          sizeof ( FT_Byte ),
-                          (void*)&load->exec->glyphIns,
-                          n_ins );
-
-      load->exec->glyphSize = (FT_UInt)tmp;
-      if ( error )
-        return error;
-
-      load->glyph->control_len  = n_ins;
-      load->glyph->control_data = load->exec->glyphIns;
-
+      /* and thus allocate the bytecode array size by ourselves     */
       if ( n_ins )
-        FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
+      {
+        if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) )
+          return error;
+
+        FT_MEM_COPY( exec->glyphIns, p, (FT_Long)n_ins );
+
+        exec->glyphSize  = n_ins;
+      }
     }
 
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
     p += n_ins;
 
-    outline = &gloader->current.outline;
-
     /* reading the point tags */
     flag       = (FT_Byte*)outline->tags;
     flag_limit = flag + n_points;
@@ -512,9 +468,6 @@
     flag      = (FT_Byte*)outline->tags;
     x         = 0;
 
-    if ( p + xy_size > limit )
-      goto Invalid_Outline;
-
     for ( ; vec < vec_limit; vec++, flag++ )
     {
       FT_Pos   delta = 0;
@@ -544,7 +497,7 @@
 
     /* reading the Y coordinates */
 
-    vec       = gloader->current.outline.points;
+    vec       = outline->points;
     vec_limit = vec + n_points;
     flag      = (FT_Byte*)outline->tags;
     y         = 0;
@@ -827,8 +780,7 @@
   TT_Hint_Glyph( TT_Loader  loader,
                  FT_Bool    is_composite )
   {
-#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
-    defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     TT_Face    face   = loader->face;
     TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
 #endif
@@ -836,35 +788,34 @@
     TT_GlyphZone  zone = &loader->zone;
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
-    FT_Long       n_ins;
+    TT_ExecContext  exec  = loader->exec;
+    FT_Long         n_ins = exec->glyphSize;
 #else
     FT_UNUSED( is_composite );
 #endif
 
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
-    n_ins = loader->glyph->control_len;
-
     /* save original point positions in `org' array */
     if ( n_ins > 0 )
       FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points );
 
     /* Reset graphics state. */
-    loader->exec->GS = loader->size->GS;
+    exec->GS = loader->size->GS;
 
     /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */
     /*      completely refer to the (already) hinted subglyphs.     */
     if ( is_composite )
     {
-      loader->exec->metrics.x_scale = 1 << 16;
-      loader->exec->metrics.y_scale = 1 << 16;
+      exec->metrics.x_scale = 1 << 16;
+      exec->metrics.y_scale = 1 << 16;
 
       FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points );
     }
     else
     {
-      loader->exec->metrics.x_scale = loader->size->metrics->x_scale;
-      loader->exec->metrics.y_scale = loader->size->metrics->y_scale;
+      exec->metrics.x_scale = loader->size->metrics->x_scale;
+      exec->metrics.y_scale = loader->size->metrics->y_scale;
     }
 #endif
 
@@ -884,53 +835,37 @@
     {
       FT_Error  error;
 
-      FT_GlyphLoader  gloader         = loader->gloader;
-      FT_Outline      current_outline = gloader->current.outline;
 
+      TT_Set_CodeRange( exec, tt_coderange_glyph, exec->glyphIns, n_ins );
 
-      TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
-                        loader->exec->glyphIns, n_ins );
+      exec->is_composite = is_composite;
+      exec->pts          = *zone;
 
-      loader->exec->is_composite = is_composite;
-      loader->exec->pts          = *zone;
-
-      error = TT_Run_Context( loader->exec );
-      if ( error && loader->exec->pedantic_hinting )
+      error = TT_Run_Context( exec );
+      if ( error && exec->pedantic_hinting )
         return error;
 
       /* store drop-out mode in bits 5-7; set bit 2 also as a marker */
-      current_outline.tags[0] |=
-        ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE;
+      loader->gloader->current.outline.tags[0] |=
+        ( exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE;
     }
 
 #endif
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     /* Save possibly modified glyph phantom points unless in v40 backward  */
     /* compatibility mode, where no movement on the x axis means no reason */
     /* to change bearings or advance widths.                               */
-    if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
-            loader->exec->backward_compatibility ) )
-    {
-#endif
-      loader->pp1 = zone->cur[zone->n_points - 4];
-      loader->pp2 = zone->cur[zone->n_points - 3];
-      loader->pp3 = zone->cur[zone->n_points - 2];
-      loader->pp4 = zone->cur[zone->n_points - 1];
+
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-    }
+    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
+         exec->backward_compatibility )
+      return FT_Err_Ok;
 #endif
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
-    {
-      if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN )
-        FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 );
-
-      else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN )
-        FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 );
-    }
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
+    loader->pp1 = zone->cur[zone->n_points - 4];
+    loader->pp2 = zone->cur[zone->n_points - 3];
+    loader->pp3 = zone->cur[zone->n_points - 2];
+    loader->pp4 = zone->cur[zone->n_points - 1];
 
     return FT_Err_Ok;
   }
@@ -949,10 +884,10 @@
   static FT_Error
   TT_Process_Simple_Glyph( TT_Loader  loader )
   {
-    FT_GlyphLoader  gloader = loader->gloader;
-    FT_Error        error   = FT_Err_Ok;
-    FT_Outline*     outline;
-    FT_Int          n_points;
+    FT_Error        error    = FT_Err_Ok;
+    FT_GlyphLoader  gloader  = loader->gloader;
+    FT_Outline*     outline  = &gloader->current.outline;
+    FT_Int          n_points = outline->n_points;
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     FT_Memory   memory    = loader->face->root.memory;
@@ -960,11 +895,7 @@
 #endif
 
 
-    outline  = &gloader->current.outline;
-    n_points = outline->n_points;
-
     /* set phantom points */
-
     outline->points[n_points    ] = loader->pp1;
     outline->points[n_points + 1] = loader->pp2;
     outline->points[n_points + 2] = loader->pp3;
@@ -976,7 +907,7 @@
 
     if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
     {
-      if ( FT_NEW_ARRAY( unrounded, n_points ) )
+      if ( FT_QNEW_ARRAY( unrounded, n_points ) )
         goto Exit;
 
       /* Deltas apply to the unscaled data. */
@@ -998,16 +929,6 @@
     }
 
     {
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      TT_Face    face   = loader->face;
-      TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
-
-      FT_String*  family         = face->root.family_name;
-      FT_UInt     ppem           = loader->size->metrics->x_ppem;
-      FT_String*  style          = face->root.style_name;
-      FT_UInt     x_scale_factor = 1000;
-#endif
-
       FT_Vector*  vec   = outline->points;
       FT_Vector*  limit = outline->points + n_points;
 
@@ -1017,52 +938,6 @@
       FT_Bool  do_scale = FALSE;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
-      {
-        /* scale, but only if enabled and only if TT hinting is being used */
-        if ( IS_HINTED( loader->load_flags ) )
-          x_scale_factor = sph_test_tweak_x_scaling( face,
-                                                     family,
-                                                     ppem,
-                                                     style,
-                                                     loader->glyph_index );
-        /* scale the glyph */
-        if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ||
-             x_scale_factor != 1000                         )
-        {
-          x_scale = FT_MulDiv( loader->size->metrics->x_scale,
-                               (FT_Long)x_scale_factor, 1000 );
-          y_scale = loader->size->metrics->y_scale;
-
-          /* compensate for any scaling by de/emboldening; */
-          /* the amount was determined via experimentation */
-          if ( x_scale_factor != 1000 && ppem > 11 )
-          {
-#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-            FT_Vector*  orig_points = outline->points;
-
-
-            if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
-              outline->points = unrounded;
-#endif
-            FT_Outline_EmboldenXY( outline,
-                                   FT_MulFix( 1280 * ppem,
-                                              1000 - x_scale_factor ),
-                                   0 );
-#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-            if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
-              outline->points = orig_points;
-#endif
-          }
-          do_scale = TRUE;
-        }
-      }
-      else
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       {
         /* scale the glyph */
         if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
@@ -1331,12 +1206,12 @@
                               FT_UInt    start_contour )
   {
     FT_Error     error;
-    FT_Outline*  outline;
+    FT_Outline*  outline = &loader->gloader->base.outline;
+    FT_Stream    stream = loader->stream;
+    FT_UShort    n_ins;
     FT_UInt      i;
 
 
-    outline = &loader->gloader->base.outline;
-
     /* make room for phantom points */
     error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader,
                                          outline->n_points + 4,
@@ -1352,11 +1227,14 @@
 #ifdef TT_USE_BYTECODE_INTERPRETER
 
     {
-      FT_Stream  stream = loader->stream;
-      FT_UShort  n_ins, max_ins;
-      FT_ULong   tmp;
+      TT_ExecContext  exec = loader->exec;
+      FT_Memory       memory = exec->memory;
 
 
+      if ( exec->glyphSize )
+        FT_FREE( exec->glyphIns );
+      exec->glyphSize = 0;
+
       /* TT_Load_Composite_Glyph only gives us the offset of instructions */
       /* so we read them here                                             */
       if ( FT_STREAM_SEEK( loader->ins_pos ) ||
@@ -1365,39 +1243,24 @@
 
       FT_TRACE5(( "  Instructions size = %hu\n", n_ins ));
 
-      /* check it */
-      max_ins = loader->face->max_profile.maxSizeOfInstructions;
-      if ( n_ins > max_ins )
-      {
-        /* don't trust `maxSizeOfInstructions'; */
-        /* only do a rough safety check         */
-        if ( n_ins > loader->byte_len )
-        {
-          FT_TRACE1(( "TT_Process_Composite_Glyph:"
-                      " too many instructions (%hu) for glyph with length %u\n",
-                      n_ins, loader->byte_len ));
-          return FT_THROW( Too_Many_Hints );
-        }
-
-        tmp   = loader->exec->glyphSize;
-        error = Update_Max( loader->exec->memory,
-                            &tmp,
-                            sizeof ( FT_Byte ),
-                            (void*)&loader->exec->glyphIns,
-                            n_ins );
-
-        loader->exec->glyphSize = (FT_UShort)tmp;
-        if ( error )
-          return error;
-      }
-      else if ( n_ins == 0 )
+      if ( !n_ins )
         return FT_Err_Ok;
 
-      if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) )
+      /* don't trust `maxSizeOfInstructions'; */
+      /* only do a rough safety check         */
+      if ( n_ins > loader->byte_len )
+      {
+        FT_TRACE1(( "TT_Process_Composite_Glyph:"
+                    " too many instructions (%hu) for glyph with length %u\n",
+                    n_ins, loader->byte_len ));
+        return FT_THROW( Too_Many_Hints );
+      }
+
+      if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins )  ||
+           FT_STREAM_READ( exec->glyphIns, n_ins ) )
         return error;
 
-      loader->glyph->control_data = loader->exec->glyphIns;
-      loader->glyph->control_len  = n_ins;
+      exec->glyphSize = n_ins;
     }
 
 #endif
@@ -1501,45 +1364,31 @@
   static void
   tt_loader_set_pp( TT_Loader  loader )
   {
-    FT_Bool  subpixel_hinting = 0;
-    FT_Bool  grayscale        = 0;
-    FT_Bool  use_aw_2         = 0;
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( loader->face );
-#endif
-
-
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
-    {
-      subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting
-                                      : 0;
-      grayscale        = loader->exec ? loader->exec->grayscale
-                                      : 0;
-    }
-#endif
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
-    {
-      subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting_lean
-                                      : 0;
-      grayscale        = loader->exec ? loader->exec->grayscale_cleartype
-                                      : 0;
-    }
-#endif
-
-    use_aw_2 = FT_BOOL( subpixel_hinting && grayscale );
-
     loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
     loader->pp1.y = 0;
     loader->pp2.x = loader->pp1.x + loader->advance;
     loader->pp2.y = 0;
 
-    loader->pp3.x = use_aw_2 ? loader->advance / 2 : 0;
+    loader->pp3.x = 0;
     loader->pp3.y = loader->bbox.yMax + loader->top_bearing;
-    loader->pp4.x = use_aw_2 ? loader->advance / 2 : 0;
+    loader->pp4.x = 0;
     loader->pp4.y = loader->pp3.y - loader->vadvance;
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    {
+      TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( loader->face );
+
+
+      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
+           loader->exec                                             &&
+           loader->exec->subpixel_hinting_lean                      &&
+           loader->exec->grayscale_cleartype                        )
+      {
+        loader->pp3.x = loader->advance / 2;
+        loader->pp4.x = loader->advance / 2;
+      }
+    }
+#endif
   }
 
 
@@ -1662,8 +1511,14 @@
     else
 
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
+    {
+      FT_ULong  len;
 
-      offset = tt_face_get_location( face, glyph_index, &loader->byte_len );
+
+      offset = tt_face_get_location( FT_FACE( face ), glyph_index, &len );
+
+      loader->byte_len = (FT_UInt)len;
+    }
 
     if ( loader->byte_len > 0 )
     {
@@ -1889,10 +1744,7 @@
         short        i, limit;
         FT_SubGlyph  subglyph;
 
-        FT_Outline  outline;
-        FT_Vector*  points    = NULL;
-        char*       tags      = NULL;
-        short*      contours  = NULL;
+        FT_Outline  outline = { 0, 0, NULL, NULL, NULL, 0 };
         FT_Vector*  unrounded = NULL;
 
 
@@ -1900,18 +1752,14 @@
 
         /* construct an outline structure for              */
         /* communication with `TT_Vary_Apply_Glyph_Deltas' */
-        outline.n_contours = outline.n_points = limit;
-
-        outline.points   = NULL;
-        outline.tags     = NULL;
-        outline.contours = NULL;
-
-        if ( FT_NEW_ARRAY( points, limit + 4 )    ||
-             FT_NEW_ARRAY( tags, limit + 4 )      ||
-             FT_NEW_ARRAY( contours, limit + 4 )  ||
-             FT_NEW_ARRAY( unrounded, limit + 4 ) )
+        if ( FT_QNEW_ARRAY( outline.points, limit + 4 ) ||
+             FT_QNEW_ARRAY( outline.tags, limit )       ||
+             FT_QNEW_ARRAY( outline.contours, limit )   ||
+             FT_QNEW_ARRAY( unrounded, limit + 4 )      )
           goto Exit1;
 
+        outline.n_contours = outline.n_points = limit;
+
         subglyph = gloader->current.subglyphs;
 
         for ( i = 0; i < limit; i++, subglyph++ )
@@ -1919,20 +1767,16 @@
           /* 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;
+          outline.points[i].x = subglyph->arg1;
+          outline.points[i].y = subglyph->arg2;
+          outline.tags[i]     = ON_CURVE_POINT;
+          outline.contours[i] = i;
         }
 
-        points[i++] = loader->pp1;
-        points[i++] = loader->pp2;
-        points[i++] = loader->pp3;
-        points[i  ] = loader->pp4;
-
-        outline.points   = points;
-        outline.tags     = tags;
-        outline.contours = contours;
+        outline.points[i++] = loader->pp1;
+        outline.points[i++] = loader->pp2;
+        outline.points[i++] = loader->pp3;
+        outline.points[i  ] = loader->pp4;
 
         /* this call provides additional offsets */
         /* for each component's translation      */
@@ -1947,8 +1791,8 @@
         {
           if ( subglyph->flags & ARGS_ARE_XY_VALUES )
           {
-            subglyph->arg1 = (FT_Int16)points[i].x;
-            subglyph->arg2 = (FT_Int16)points[i].y;
+            subglyph->arg1 = (FT_Int16)outline.points[i].x;
+            subglyph->arg2 = (FT_Int16)outline.points[i].y;
           }
         }
 
@@ -2332,8 +2176,7 @@
 #ifdef TT_USE_BYTECODE_INTERPRETER
     FT_Error   error;
     FT_Bool    pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
-#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
-    defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     TT_Driver  driver   = (TT_Driver)FT_FACE_DRIVER( glyph->face );
 #endif
 #endif
@@ -2353,20 +2196,6 @@
       FT_Bool         grayscale_cleartype;
 #endif
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      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_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       FT_Bool  reexecute = FALSE;
 
 
@@ -2386,6 +2215,9 @@
       if ( !exec )
         return FT_THROW( Could_Not_Find_Context );
 
+      grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
+                             FT_RENDER_MODE_MONO             );
+
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
       {
@@ -2402,6 +2234,7 @@
           FT_BOOL( subpixel_hinting_lean    &&
                    ( load_flags           &
                      FT_LOAD_TARGET_LCD_V ) );
+        grayscale = FT_BOOL( grayscale && !subpixel_hinting_lean );
       }
       else
       {
@@ -2411,111 +2244,11 @@
       }
 #endif
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
-      {
-        subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) !=
-                                      FT_RENDER_MODE_MONO               )  &&
-                                    SPH_OPTION_SET_SUBPIXEL                );
-
-        if ( subpixel_hinting )
-          grayscale = FALSE;
-        else if ( SPH_OPTION_SET_GRAYSCALE )
-        {
-          grayscale        = TRUE;
-          subpixel_hinting = FALSE;
-        }
-        else
-          grayscale = FALSE;
-
-        if ( FT_IS_TRICKY( glyph->face ) )
-          subpixel_hinting = FALSE;
-
-        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 = 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 ) !=
-                   TT_LOAD_COMPATIBLE_WIDTHS );
-        exec->symmetrical_smoothing =
-          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
-                   TT_LOAD_SYMMETRICAL_SMOOTHING );
-        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 */
-
-      }
-      else
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
-        grayscale = FT_BOOL( !subpixel_hinting_lean               &&
-                             FT_LOAD_TARGET_MODE( load_flags ) !=
-                               FT_RENDER_MODE_MONO                );
-      else
-#endif
-        grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
-                               FT_RENDER_MODE_MONO             );
-
       error = TT_Load_Context( exec, face, size );
       if ( error )
         return error;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
       {
-        /* a change from mono to subpixel rendering (and vice versa) */
-        /* requires a re-execution of the CVT program                */
-        if ( subpixel_hinting != exec->subpixel_hinting )
-        {
-          FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
-                      " re-executing `prep' table\n" ));
-
-          exec->subpixel_hinting = subpixel_hinting;
-          reexecute              = TRUE;
-        }
-
-        /* a change from mono to grayscale rendering (and vice versa) */
-        /* requires a re-execution of the CVT program                 */
-        if ( grayscale != exec->grayscale )
-        {
-          FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
-                      " re-executing `prep' table\n" ));
-
-          exec->grayscale = grayscale;
-          reexecute       = TRUE;
-        }
-      }
-      else
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
-      {
-
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
         if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
         {
@@ -2573,14 +2306,6 @@
       if ( exec->GS.instruct_control & 2 )
         exec->GS = tt_default_graphics_state;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      /* check whether we have a font hinted for ClearType --           */
-      /* note that this flag can also be modified in a glyph's bytecode */
-      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
-           exec->GS.instruct_control & 4                            )
-        exec->ignore_x_mode = FALSE;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
       /*
        * Toggle backward compatibility according to what font wants, except
@@ -2617,13 +2342,6 @@
            !( driver->interpreter_version == TT_INTERPRETER_VERSION_40  &&
               exec->backward_compatibility                              ) &&
 #endif
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-           !( driver->interpreter_version == TT_INTERPRETER_VERSION_38  &&
-              !SPH_OPTION_BITMAP_WIDTHS                                 &&
-              FT_LOAD_TARGET_MODE( loader->load_flags ) !=
-                                                   FT_RENDER_MODE_MONO  &&
-              exec->compatible_widths                                   ) &&
-#endif
            !face->postscript.isFixedPitch                                 )
       {
         loader->widthp = size->widthp;
@@ -2857,7 +2575,9 @@
 #ifdef FT_CONFIG_OPTION_SVG
 
     /* check for OT-SVG */
-    if ( ( load_flags & FT_LOAD_COLOR ) && face->svg )
+    if ( ( load_flags & FT_LOAD_NO_SVG ) == 0 &&
+         ( load_flags & FT_LOAD_COLOR )       &&
+         face->svg                            )
     {
       SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
 
@@ -2955,6 +2675,9 @@
 
       if ( IS_HINTED( load_flags ) )
       {
+        glyph->control_data = loader.exec->glyphIns;
+        glyph->control_len  = loader.exec->glyphSize;
+
         if ( loader.exec->GS.scan_control )
         {
           /* convert scan conversion mode to FT_OUTLINE_XXX flags */
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index d983e9e..ad4f266 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -45,6 +45,7 @@
 #include <freetype/internal/ftcalc.h>
 #include <freetype/internal/ftstream.h>
 #include <freetype/internal/sfnt.h>
+#include <freetype/internal/services/svmetric.h>
 #include <freetype/tttags.h>
 #include <freetype/ttnameid.h>
 #include <freetype/ftmm.h>
@@ -465,7 +466,7 @@
     if ( store_offset )
     {
       error = tt_var_load_item_variation_store(
-                face,
+                FT_FACE( face ),
                 table_offset + store_offset,
                 &table->itemStore );
       if ( error )
@@ -475,7 +476,7 @@
     if ( axisMap_offset )
     {
       error = tt_var_load_delta_set_index_mapping(
-                face,
+                FT_FACE( face ),
                 table_offset + axisMap_offset,
                 &table->axisMap,
                 &table->itemStore,
@@ -492,10 +493,11 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  tt_var_load_item_variation_store( TT_Face          face,
+  tt_var_load_item_variation_store( FT_Face          face,      /* TT_Face */
                                     FT_ULong         offset,
                                     GX_ItemVarStore  itemStore )
   {
+    TT_Face    ttface = (TT_Face)face;
     FT_Stream  stream = FT_FACE_STREAM( face );
     FT_Memory  memory = stream->memory;
 
@@ -507,10 +509,10 @@
     FT_UShort  axis_count;
     FT_UInt    region_count;
 
-    FT_UInt  i, j, k;
+    FT_UInt  i, j;
     FT_Bool  long_words;
 
-    GX_Blend   blend           = face->blend;
+    GX_Blend   blend           = ttface->blend;
     FT_ULong*  dataOffsetArray = NULL;
 
 
@@ -619,9 +621,10 @@
     {
       GX_ItemVarData  varData = &itemStore->varData[i];
 
-      FT_UInt  item_count;
-      FT_UInt  word_delta_count;
-      FT_UInt  region_idx_count;
+      FT_UInt    item_count;
+      FT_UShort  word_delta_count;
+      FT_UInt    region_idx_count;
+      FT_UInt    per_region_size;
 
 
       if ( FT_STREAM_SEEK( offset + dataOffsetArray[i] ) )
@@ -658,6 +661,8 @@
       if ( FT_NEW_ARRAY( varData->regionIndices, region_idx_count ) )
         goto Exit;
       varData->regionIdxCount = region_idx_count;
+      varData->wordDeltaCount = word_delta_count;
+      varData->longWords      = long_words;
 
       for ( j = 0; j < varData->regionIdxCount; j++ )
       {
@@ -673,37 +678,22 @@
         }
       }
 
-      /* Parse delta set.                                                  */
-      /*                                                                   */
-      /* On input, deltas are (word_delta_count + region_idx_count) bytes  */
-      /* each if `long_words` isn't set, and twice as much otherwise.      */
-      /*                                                                   */
-      /* On output, deltas are expanded to `region_idx_count` shorts each. */
-      if ( FT_NEW_ARRAY( varData->deltaSet, item_count * region_idx_count ) )
-        goto Exit;
-      varData->itemCount = item_count;
+      per_region_size = word_delta_count + region_idx_count;
+      if ( long_words )
+        per_region_size *= 2;
 
-      for ( j = 0; j < item_count * region_idx_count; )
+      if ( FT_NEW_ARRAY( varData->deltaSet, per_region_size * item_count ) )
+        goto Exit;
+      if ( FT_Stream_Read( stream,
+                           varData->deltaSet,
+                           per_region_size * item_count ) )
       {
-        if ( long_words )
-        {
-          for ( k = 0; k < word_delta_count; k++, j++ )
-            if ( FT_READ_LONG( varData->deltaSet[j] ) )
-              goto Exit;
-          for ( ; k < region_idx_count; k++, j++ )
-            if ( FT_READ_SHORT( varData->deltaSet[j] ) )
-              goto Exit;
-        }
-        else
-        {
-          for ( k = 0; k < word_delta_count; k++, j++ )
-            if ( FT_READ_SHORT( varData->deltaSet[j] ) )
-              goto Exit;
-          for ( ; k < region_idx_count; k++, j++ )
-            if ( FT_READ_CHAR( varData->deltaSet[j] ) )
-              goto Exit;
-        }
+        FT_TRACE2(( "deltaSet read failed." ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
       }
+
+      varData->itemCount = item_count;
     }
 
   Exit:
@@ -714,7 +704,7 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  tt_var_load_delta_set_index_mapping( TT_Face            face,
+  tt_var_load_delta_set_index_mapping( FT_Face            face, /* TT_Face */
                                        FT_ULong           offset,
                                        GX_DeltaSetIdxMap  map,
                                        GX_ItemVarStore    itemStore,
@@ -941,7 +931,7 @@
     }
 
     error = tt_var_load_item_variation_store(
-              face,
+              FT_FACE( face ),
               table_offset + store_offset,
               &table->itemStore );
     if ( error )
@@ -950,7 +940,7 @@
     if ( widthMap_offset )
     {
       error = tt_var_load_delta_set_index_mapping(
-                face,
+                FT_FACE( face ),
                 table_offset + widthMap_offset,
                 &table->widthMap,
                 &table->itemStore,
@@ -992,24 +982,30 @@
 
 
   FT_LOCAL_DEF( FT_ItemVarDelta )
-  tt_var_get_item_delta( TT_Face          face,
+  tt_var_get_item_delta( FT_Face          face,        /* TT_Face */
                          GX_ItemVarStore  itemStore,
                          FT_UInt          outerIndex,
                          FT_UInt          innerIndex )
   {
+    TT_Face    ttface = (TT_Face)face;
     FT_Stream  stream = FT_FACE_STREAM( face );
     FT_Memory  memory = stream->memory;
     FT_Error   error  = FT_Err_Ok;
 
     GX_ItemVarData    varData;
-    FT_ItemVarDelta*  deltaSet;
+    FT_ItemVarDelta*  deltaSet = NULL;
+    FT_ItemVarDelta   deltaSetStack[16];
+
+    FT_Fixed*  scalars = NULL;
+    FT_Fixed   scalarsStack[16];
 
     FT_UInt          master, j;
-    FT_Fixed*        scalars = NULL;
-    FT_ItemVarDelta  returnValue;
+    FT_ItemVarDelta  returnValue = 0;
+    FT_UInt          per_region_size;
+    FT_Byte*         bytes;
 
 
-    if ( !face->blend || !face->blend->normalizedcoords )
+    if ( !ttface->blend || !ttface->blend->normalizedcoords )
       return 0;
 
     /* OpenType 1.8.4+: No variation data for this item */
@@ -1023,15 +1019,48 @@
     if ( outerIndex >= itemStore->dataCount )
       return 0; /* Out of range. */
 
-    varData  = &itemStore->varData[outerIndex];
-    deltaSet = FT_OFFSET( varData->deltaSet,
-                          varData->regionIdxCount * innerIndex );
+    varData = &itemStore->varData[outerIndex];
 
     if ( innerIndex >= varData->itemCount )
       return 0; /* Out of range. */
 
-    if ( FT_QNEW_ARRAY( scalars, varData->regionIdxCount ) )
-      return 0;
+    if ( varData->regionIdxCount < 16 )
+    {
+      deltaSet = deltaSetStack;
+      scalars  = scalarsStack;
+    }
+    else
+    {
+      if ( FT_QNEW_ARRAY( deltaSet, varData->regionIdxCount ) )
+        goto Exit;
+      if ( FT_QNEW_ARRAY( scalars, varData->regionIdxCount ) )
+        goto Exit;
+    }
+
+    /* Parse delta set.                                            */
+    /*                                                             */
+    /* Deltas are (word_delta_count + region_idx_count) bytes each */
+    /* if `longWords` isn't set, and twice as much otherwise.      */
+    per_region_size = varData->wordDeltaCount + varData->regionIdxCount;
+    if ( varData->longWords )
+      per_region_size *= 2;
+
+    bytes = varData->deltaSet + per_region_size * innerIndex;
+
+    if ( varData->longWords )
+    {
+      for ( master = 0; master < varData->wordDeltaCount; master++ )
+        deltaSet[master] = FT_NEXT_LONG( bytes );
+      for ( ; master < varData->regionIdxCount; master++ )
+        deltaSet[master] = FT_NEXT_SHORT( bytes );
+    }
+    else
+    {
+      for ( master = 0; master < varData->wordDeltaCount; master++ )
+        deltaSet[master] = FT_NEXT_SHORT( bytes );
+      for ( ; master < varData->regionIdxCount; master++ )
+        deltaSet[master] = FT_NEXT_CHAR( bytes );
+    }
 
     /* outer loop steps through master designs to be blended */
     for ( master = 0; master < varData->regionIdxCount; master++ )
@@ -1060,27 +1089,27 @@
         else if ( axis->peakCoord == 0 )
           continue;
 
-        else if ( face->blend->normalizedcoords[j] == axis->peakCoord )
+        else if ( ttface->blend->normalizedcoords[j] == axis->peakCoord )
           continue;
 
         /* ignore this region if coords are out of range */
-        else if ( face->blend->normalizedcoords[j] <= axis->startCoord ||
-                  face->blend->normalizedcoords[j] >= axis->endCoord   )
+        else if ( ttface->blend->normalizedcoords[j] <= axis->startCoord ||
+                  ttface->blend->normalizedcoords[j] >= axis->endCoord   )
         {
           scalar = 0;
           break;
         }
 
         /* cumulative product of all the axis scalars */
-        else if ( face->blend->normalizedcoords[j] < axis->peakCoord )
+        else if ( ttface->blend->normalizedcoords[j] < axis->peakCoord )
           scalar =
             FT_MulDiv( scalar,
-                       face->blend->normalizedcoords[j] - axis->startCoord,
+                       ttface->blend->normalizedcoords[j] - axis->startCoord,
                        axis->peakCoord - axis->startCoord );
         else
           scalar =
             FT_MulDiv( scalar,
-                       axis->endCoord - face->blend->normalizedcoords[j],
+                       axis->endCoord - ttface->blend->normalizedcoords[j],
                        axis->endCoord - axis->peakCoord );
 
       } /* per-axis loop */
@@ -1106,7 +1135,11 @@
      */
     returnValue = FT_MulAddFix( scalars, deltaSet, varData->regionIdxCount );
 
-    FT_FREE( scalars );
+  Exit:
+    if ( scalars != scalarsStack )
+      FT_FREE( scalars );
+    if ( deltaSet != deltaSetStack )
+      FT_FREE( deltaSet );
 
     return returnValue;
   }
@@ -1206,7 +1239,7 @@
       innerIndex = gindex;
     }
 
-    delta = tt_var_get_item_delta( face,
+    delta = tt_var_get_item_delta( FT_FACE( face ),
                                    &table->itemStore,
                                    outerIndex,
                                    innerIndex );
@@ -1229,20 +1262,20 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  tt_hadvance_adjust( TT_Face  face,
+  tt_hadvance_adjust( FT_Face  face,    /* TT_Face */
                       FT_UInt  gindex,
                       FT_Int  *avalue )
   {
-    return tt_hvadvance_adjust( face, gindex, avalue, 0 );
+    return tt_hvadvance_adjust( (TT_Face)face, gindex, avalue, 0 );
   }
 
 
   FT_LOCAL_DEF( FT_Error )
-  tt_vadvance_adjust( TT_Face  face,
+  tt_vadvance_adjust( FT_Face  face,    /* TT_Face */
                       FT_UInt  gindex,
                       FT_Int  *avalue )
   {
-    return tt_hvadvance_adjust( face, gindex, avalue, 1 );
+    return tt_hvadvance_adjust( (TT_Face)face, gindex, avalue, 1 );
   }
 
 
@@ -1389,7 +1422,7 @@
     records_offset = FT_STREAM_POS();
 
     error = tt_var_load_item_variation_store(
-              face,
+              FT_FACE( face ),
               table_offset + store_offset,
               &blend->mvar_table->itemStore );
     if ( error )
@@ -1488,16 +1521,19 @@
    *     The font face.
    */
   FT_LOCAL_DEF( void )
-  tt_apply_mvar( TT_Face  face )
+  tt_apply_mvar( FT_Face  face )  /* TT_Face */
   {
-    GX_Blend  blend = face->blend;
+    TT_Face  ttface = (TT_Face)face;
+
+    GX_Blend  blend = ttface->blend;
     GX_Value  value, limit;
+
     FT_Short  mvar_hasc_delta = 0;
     FT_Short  mvar_hdsc_delta = 0;
     FT_Short  mvar_hlgp_delta = 0;
 
 
-    if ( !( face->variation_support & TT_FACE_FLAG_VAR_MVAR ) )
+    if ( !( ttface->variation_support & TT_FACE_FLAG_VAR_MVAR ) )
       return;
 
     value = blend->mvar_table->values;
@@ -1505,7 +1541,7 @@
 
     for ( ; value < limit; value++ )
     {
-      FT_Short*  p = ft_var_get_value_pointer( face, value->tag );
+      FT_Short*  p = ft_var_get_value_pointer( ttface, value->tag );
       FT_Int     delta;
 
 
@@ -1543,9 +1579,7 @@
     /* adjust all derived values */
     {
       FT_Service_MetricsVariations  var =
-        (FT_Service_MetricsVariations)face->face_var;
-
-      FT_Face  root = &face->root;
+        (FT_Service_MetricsVariations)ttface->face_var;
 
       /*
        * Apply the deltas of hasc, hdsc and hlgp to the FT_Face's ascender,
@@ -1573,23 +1607,23 @@
        *    whether they were actually changed or the font had the OS/2 table's
        *    fsSelection's bit 7 (USE_TYPO_METRICS) set.
        */
-      FT_Short  current_line_gap = root->height - root->ascender +
-                                   root->descender;
+      FT_Short  current_line_gap = face->height - face->ascender +
+                                   face->descender;
 
 
-      root->ascender  = root->ascender + mvar_hasc_delta;
-      root->descender = root->descender + mvar_hdsc_delta;
-      root->height    = root->ascender - root->descender +
+      face->ascender  = face->ascender + mvar_hasc_delta;
+      face->descender = face->descender + mvar_hdsc_delta;
+      face->height    = face->ascender - face->descender +
                         current_line_gap + mvar_hlgp_delta;
 
-      root->underline_position  = face->postscript.underlinePosition -
-                                  face->postscript.underlineThickness / 2;
-      root->underline_thickness = face->postscript.underlineThickness;
+      face->underline_position  = ttface->postscript.underlinePosition -
+                                  ttface->postscript.underlineThickness / 2;
+      face->underline_thickness = ttface->postscript.underlineThickness;
 
       /* iterate over all FT_Size objects and call `var->size_reset' */
       /* to propagate the metrics changes                            */
       if ( var && var->size_reset )
-        FT_List_Iterate( &root->sizes_list,
+        FT_List_Iterate( &face->sizes_list,
                          ft_size_reset_iterator,
                          (void*)var );
     }
@@ -2102,7 +2136,7 @@
             innerIndex = table->axisMap.innerIndex[idx];
           }
 
-          delta = tt_var_get_item_delta( face,
+          delta = tt_var_get_item_delta( FT_FACE( face ),
                                          &table->itemStore,
                                          outerIndex,
                                          innerIndex );
@@ -2264,11 +2298,12 @@
    *   FreeType error code.  0 means success.
    */
   FT_LOCAL_DEF( FT_Error )
-  TT_Get_MM_Var( TT_Face      face,
+  TT_Get_MM_Var( FT_Face      face,    /* TT_Face */
                  FT_MM_Var*  *master )
   {
-    FT_Stream            stream     = face->root.stream;
-    FT_Memory            memory     = face->root.memory;
+    TT_Face              ttface     = (TT_Face)face;
+    FT_Stream            stream     = FT_FACE_STREAM( face );
+    FT_Memory            memory     = FT_FACE_MEMORY( face );
     FT_ULong             table_len;
     FT_Error             error      = FT_Err_Ok;
     FT_ULong             fvar_start = 0;
@@ -2332,19 +2367,19 @@
     /* the default instance, which might be missing in the table of named */
     /* instances (in 'fvar').  This value is validated in `sfobjs.c` and  */
     /* may be reset to 0 if consistency checks fail.                      */
-    num_instances = (FT_UInt)face->root.style_flags >> 16;
+    num_instances = (FT_UInt)face->style_flags >> 16;
 
     /* read the font data and set up the internal representation */
     /* if not already done                                       */
 
-    need_init = !face->blend;
+    need_init = !ttface->blend;
 
     if ( need_init )
     {
       FT_TRACE2(( "FVAR " ));
 
-      if ( FT_SET_ERROR( face->goto_table( face, TTAG_fvar,
-                                           stream, &table_len ) ) )
+      if ( FT_SET_ERROR( ttface->goto_table( ttface, TTAG_fvar,
+                                             stream, &table_len ) ) )
       {
         FT_TRACE1(( "is missing\n" ));
         goto Exit;
@@ -2377,14 +2412,14 @@
                   fvar_head.axisCount,
                   fvar_head.axisCount == 1 ? "is" : "es" ));
 
-      if ( FT_NEW( face->blend ) )
+      if ( FT_NEW( ttface->blend ) )
         goto Exit;
 
-      num_axes              = fvar_head.axisCount;
-      face->blend->num_axis = num_axes;
+      num_axes                = fvar_head.axisCount;
+      ttface->blend->num_axis = num_axes;
     }
     else
-      num_axes = face->blend->num_axis;
+      num_axes = ttface->blend->num_axis;
 
     /* prepare storage area for MM data; this cannot overflow   */
     /* 32-bit arithmetic because of the size limits used in the */
@@ -2413,16 +2448,16 @@
 
     if ( need_init )
     {
-      face->blend->mmvar_len = mmvar_size       +
-                               axis_flags_size  +
-                               axis_size        +
-                               namedstyle_size  +
-                               next_coords_size +
-                               next_name_size;
+      ttface->blend->mmvar_len = mmvar_size       +
+                                 axis_flags_size  +
+                                 axis_size        +
+                                 namedstyle_size  +
+                                 next_coords_size +
+                                 next_name_size;
 
-      if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) )
+      if ( FT_ALLOC( mmvar, ttface->blend->mmvar_len ) )
         goto Exit;
-      face->blend->mmvar = mmvar;
+      ttface->blend->mmvar = mmvar;
 
       /* set up pointers and offsets into the `mmvar' array; */
       /* the data gets filled in later on                    */
@@ -2528,27 +2563,27 @@
 
       /* named instance coordinates are stored as design coordinates; */
       /* we have to convert them to normalized coordinates also       */
-      if ( FT_NEW_ARRAY( face->blend->normalized_stylecoords,
+      if ( FT_NEW_ARRAY( ttface->blend->normalized_stylecoords,
                          num_axes * num_instances ) )
         goto Exit;
 
-      if ( fvar_head.instanceCount && !face->blend->avar_loaded )
+      if ( fvar_head.instanceCount && !ttface->blend->avar_loaded )
       {
         FT_ULong  offset = FT_STREAM_POS();
 
 
-        ft_var_load_avar( face );
+        ft_var_load_avar( ttface );
 
         if ( FT_STREAM_SEEK( offset ) )
           goto Exit;
       }
 
-      FT_TRACE5(( "%d instance%s\n",
+      FT_TRACE5(( "%d named instance%s\n",
                   fvar_head.instanceCount,
                   fvar_head.instanceCount == 1 ? "" : "s" ));
 
       ns  = mmvar->namedstyle;
-      nsc = face->blend->normalized_stylecoords;
+      nsc = ttface->blend->normalized_stylecoords;
       for ( i = 0; i < fvar_head.instanceCount; i++, ns++ )
       {
         /* PostScript names add 2 bytes to the instance record size */
@@ -2571,7 +2606,7 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
         {
-          SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
+          SFNT_Service  sfnt = (SFNT_Service)ttface->sfnt;
 
           FT_String*  strname = NULL;
           FT_String*  psname  = NULL;
@@ -2583,7 +2618,7 @@
 
           if ( ns->strid != 0xFFFF )
           {
-            (void)sfnt->get_name( face,
+            (void)sfnt->get_name( ttface,
                                   (FT_UShort)ns->strid,
                                   &strname );
             if ( strname && !ft_strcmp( strname, ".notdef" ) )
@@ -2592,7 +2627,7 @@
 
           if ( ns->psid != 0xFFFF )
           {
-            (void)sfnt->get_name( face,
+            (void)sfnt->get_name( ttface,
                                   (FT_UShort)ns->psid,
                                   &psname );
             if ( psname && !ft_strcmp( psname, ".notdef" ) )
@@ -2601,7 +2636,7 @@
 
           (void)FT_STREAM_SEEK( pos );
 
-          FT_TRACE5(( "  instance %d (%s%s%s, %s%s%s)\n",
+          FT_TRACE5(( "  named instance %d (%s%s%s, %s%s%s)\n",
                       i,
                       strname ? "name: `" : "",
                       strname ? strname : "unnamed",
@@ -2615,7 +2650,7 @@
         }
 #endif /* FT_DEBUG_LEVEL_TRACE */
 
-        ft_var_to_normalized( face, num_axes, ns->coords, nsc );
+        ft_var_to_normalized( ttface, num_axes, ns->coords, nsc );
         nsc += num_axes;
 
         FT_FRAME_EXIT();
@@ -2623,15 +2658,17 @@
 
       if ( num_instances != fvar_head.instanceCount )
       {
-        SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
+        SFNT_Service  sfnt = (SFNT_Service)ttface->sfnt;
 
         FT_Int   found, dummy1, dummy2;
         FT_UInt  strid = ~0U;
 
 
-        /* the default instance is missing in array the   */
-        /* of named instances; try to synthesize an entry */
-        found = sfnt->get_name_id( face,
+        /* The default instance is missing in array the    */
+        /* of named instances; try to synthesize an entry. */
+        /* If this fails, `default_named_instance` remains */
+        /* at value zero, which doesn't do any harm.       */
+        found = sfnt->get_name_id( ttface,
                                    TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY,
                                    &dummy1,
                                    &dummy2 );
@@ -2639,7 +2676,7 @@
           strid = TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY;
         else
         {
-          found = sfnt->get_name_id( face,
+          found = sfnt->get_name_id( ttface,
                                      TT_NAME_ID_FONT_SUBFAMILY,
                                      &dummy1,
                                      &dummy2 );
@@ -2649,7 +2686,7 @@
 
         if ( found )
         {
-          found = sfnt->get_name_id( face,
+          found = sfnt->get_name_id( ttface,
                                      TT_NAME_ID_PS_NAME,
                                      &dummy1,
                                      &dummy2 );
@@ -2658,6 +2695,9 @@
             FT_TRACE5(( "TT_Get_MM_Var:"
                         " Adding default instance to named instances\n" ));
 
+            /* named instance indices start with value 1 */
+            ttface->var_default_named_instance = num_instances;
+
             ns = &mmvar->namedstyle[fvar_head.instanceCount];
 
             ns->strid = strid;
@@ -2671,7 +2711,7 @@
         }
       }
 
-      ft_var_load_mvar( face );
+      ft_var_load_mvar( ttface );
     }
 
     /* fill the output array if requested */
@@ -2681,9 +2721,9 @@
       FT_UInt  n;
 
 
-      if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) )
+      if ( FT_ALLOC( mmvar, ttface->blend->mmvar_len ) )
         goto Exit;
-      FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len );
+      FT_MEM_COPY( mmvar, ttface->blend->mmvar, ttface->blend->mmvar_len );
 
       axis_flags =
         (FT_UShort*)( (char*)mmvar + mmvar_size );
@@ -2759,7 +2799,7 @@
 
     if ( !face->blend )
     {
-      if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
+      if ( FT_SET_ERROR( TT_Get_MM_Var( FT_FACE( face ), NULL ) ) )
         goto Exit;
     }
 
@@ -2844,26 +2884,29 @@
         }
       }
 
-      if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) )
+      if ( !have_diff )
       {
-        FT_UInt  instance_index = (FT_UInt)face->root.face_index >> 16;
+        if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) )
+        {
+          FT_UInt  instance_index = (FT_UInt)face->root.face_index >> 16;
 
 
-        c = blend->normalizedcoords + i;
-        n = blend->normalized_stylecoords            +
-            ( instance_index - 1 ) * mmvar->num_axis +
-            i;
+          c = blend->normalizedcoords + i;
+          n = blend->normalized_stylecoords            +
+              ( instance_index - 1 ) * mmvar->num_axis +
+              i;
 
-        for ( j = i; j < mmvar->num_axis; j++, n++, c++ )
-          if ( *c != *n )
-            have_diff = 1;
-      }
-      else
-      {
-        c = blend->normalizedcoords + i;
-        for ( j = i; j < mmvar->num_axis; j++, c++ )
-          if ( *c != 0 )
-            have_diff = 1;
+          for ( j = i; j < mmvar->num_axis; j++, n++, c++ )
+            if ( *c != *n )
+              have_diff = 1;
+        }
+        else
+        {
+          c = blend->normalizedcoords + i;
+          for ( j = i; j < mmvar->num_axis; j++, c++ )
+            if ( *c != 0 )
+              have_diff = 1;
+        }
       }
 
       /* return value -1 indicates `no change' */
@@ -2927,9 +2970,6 @@
       }
     }
 
-    /* enforce recomputation of the PostScript name; */
-    FT_FREE( face->postscript_name );
-
   Exit:
     return error;
   }
@@ -2961,26 +3001,15 @@
    *     An array of `num_coords', each between [-1,1].
    *
    * @Return:
-   *   FreeType error code.  0 means success.
+   *   FreeType error code.  0 means success, -1 means success and unchanged
+   *   axis values.
    */
   FT_LOCAL_DEF( FT_Error )
-  TT_Set_MM_Blend( TT_Face    face,
+  TT_Set_MM_Blend( FT_Face    face,       /* TT_Face */
                    FT_UInt    num_coords,
                    FT_Fixed*  coords )
   {
-    FT_Error  error;
-
-
-    error = tt_set_mm_blend( face, num_coords, coords, 1 );
-    if ( error )
-      return error;
-
-    if ( num_coords )
-      face->root.face_flags |= FT_FACE_FLAG_VARIATION;
-    else
-      face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
-
-    return FT_Err_Ok;
+    return tt_set_mm_blend( (TT_Face)face, num_coords, coords, 1 );
   }
 
 
@@ -3008,31 +3037,34 @@
    *     An array of `num_coords', each between [-1,1].
    *
    * @Return:
-   *   FreeType error code.  0 means success.
+   *   FreeType error code.  0 means success, -1 means success and unchanged
+   *   axis values.
    */
   FT_LOCAL_DEF( FT_Error )
-  TT_Get_MM_Blend( TT_Face    face,
+  TT_Get_MM_Blend( FT_Face    face,       /* TT_Face */
                    FT_UInt    num_coords,
                    FT_Fixed*  coords )
   {
+    TT_Face  ttface = (TT_Face)face;
+
     FT_Error  error = FT_Err_Ok;
     GX_Blend  blend;
     FT_UInt   i, nc;
 
 
-    if ( !face->blend )
+    if ( !ttface->blend )
     {
       if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
         return error;
     }
 
-    blend = face->blend;
+    blend = ttface->blend;
 
     if ( !blend->coords )
     {
       /* select default instance coordinates */
       /* if no instance is selected yet      */
-      if ( FT_SET_ERROR( tt_set_mm_blend( face, 0, NULL, 1 ) ) )
+      if ( FT_SET_ERROR( tt_set_mm_blend( ttface, 0, NULL, 1 ) ) )
         return error;
     }
 
@@ -3045,7 +3077,7 @@
       nc = blend->num_axis;
     }
 
-    if ( face->doblend )
+    if ( ttface->doblend )
     {
       for ( i = 0; i < nc; i++ )
         coords[i] = blend->normalizedcoords[i];
@@ -3092,15 +3124,16 @@
    *   FreeType error code.  0 means success.
    */
   FT_LOCAL_DEF( FT_Error )
-  TT_Set_Var_Design( TT_Face    face,
+  TT_Set_Var_Design( FT_Face    face,       /* TT_Face */
                      FT_UInt    num_coords,
                      FT_Fixed*  coords )
   {
+    TT_Face     ttface = (TT_Face)face;
     FT_Error    error  = FT_Err_Ok;
     GX_Blend    blend;
     FT_MM_Var*  mmvar;
     FT_UInt     i;
-    FT_Memory   memory = face->root.memory;
+    FT_Memory   memory = FT_FACE_MEMORY( face );
 
     FT_Fixed*  c;
     FT_Fixed*  n;
@@ -3109,13 +3142,13 @@
     FT_Bool  have_diff = 0;
 
 
-    if ( !face->blend )
+    if ( !ttface->blend )
     {
       if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
         goto Exit;
     }
 
-    blend = face->blend;
+    blend = ttface->blend;
     mmvar = blend->mmvar;
 
     if ( num_coords > mmvar->num_axis )
@@ -3143,13 +3176,13 @@
       }
     }
 
-    if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) )
+    if ( FT_IS_NAMED_INSTANCE( face ) )
     {
       FT_UInt              instance_index;
       FT_Var_Named_Style*  named_style;
 
 
-      instance_index = (FT_UInt)face->root.face_index >> 16;
+      instance_index = (FT_UInt)face->face_index >> 16;
       named_style    = mmvar->namedstyle + instance_index - 1;
 
       n = named_style->coords + num_coords;
@@ -3186,22 +3219,17 @@
     if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) )
       goto Exit;
 
-    if ( !face->blend->avar_loaded )
-      ft_var_load_avar( face );
+    if ( !ttface->blend->avar_loaded )
+      ft_var_load_avar( ttface );
 
     FT_TRACE5(( "TT_Set_Var_Design:\n" ));
     FT_TRACE5(( "  normalized design coordinates:\n" ));
-    ft_var_to_normalized( face, num_coords, blend->coords, normalized );
+    ft_var_to_normalized( ttface, num_coords, blend->coords, normalized );
 
-    error = tt_set_mm_blend( face, mmvar->num_axis, normalized, 0 );
+    error = tt_set_mm_blend( ttface, mmvar->num_axis, normalized, 0 );
     if ( error )
       goto Exit;
 
-    if ( num_coords )
-      face->root.face_flags |= FT_FACE_FLAG_VARIATION;
-    else
-      face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
-
   Exit:
     FT_FREE( normalized );
     return error;
@@ -3234,28 +3262,29 @@
    *   FreeType error code.  0~means success.
    */
   FT_LOCAL_DEF( FT_Error )
-  TT_Get_Var_Design( TT_Face    face,
+  TT_Get_Var_Design( FT_Face    face,       /* TT_Face */
                      FT_UInt    num_coords,
                      FT_Fixed*  coords )
   {
-    FT_Error  error = FT_Err_Ok;
+    TT_Face   ttface = (TT_Face)face;
+    FT_Error  error  = FT_Err_Ok;
     GX_Blend  blend;
     FT_UInt   i, nc;
 
 
-    if ( !face->blend )
+    if ( !ttface->blend )
     {
       if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
         return error;
     }
 
-    blend = face->blend;
+    blend = ttface->blend;
 
     if ( !blend->coords )
     {
       /* select default instance coordinates */
       /* if no instance is selected yet      */
-      if ( FT_SET_ERROR( tt_set_mm_blend( face, 0, NULL, 1 ) ) )
+      if ( FT_SET_ERROR( tt_set_mm_blend( ttface, 0, NULL, 1 ) ) )
         return error;
     }
 
@@ -3268,7 +3297,7 @@
       nc = blend->num_axis;
     }
 
-    if ( face->doblend )
+    if ( ttface->doblend )
     {
       for ( i = 0; i < nc; i++ )
         coords[i] = blend->coords[i];
@@ -3304,29 +3333,33 @@
    *     Value 0 indicates to not use an instance.
    *
    * @Return:
-   *   FreeType error code.  0~means success.
+   *   FreeType error code.  0~means success, -1 means success and unchanged
+   *   axis values.
    */
   FT_LOCAL_DEF( FT_Error )
-  TT_Set_Named_Instance( TT_Face  face,
+  TT_Set_Named_Instance( FT_Face  face,            /* TT_Face */
                          FT_UInt  instance_index )
   {
+    TT_Face     ttface = (TT_Face)face;
     FT_Error    error;
     GX_Blend    blend;
     FT_MM_Var*  mmvar;
 
+    FT_Memory  memory = FT_FACE_MEMORY( face );
+
     FT_UInt  num_instances;
 
 
-    if ( !face->blend )
+    if ( !ttface->blend )
     {
       if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
         goto Exit;
     }
 
-    blend = face->blend;
+    blend = ttface->blend;
     mmvar = blend->mmvar;
 
-    num_instances = (FT_UInt)face->root.style_flags >> 16;
+    num_instances = (FT_UInt)face->style_flags >> 16;
 
     /* `instance_index' starts with value 1, thus `>' */
     if ( instance_index > num_instances )
@@ -3337,8 +3370,7 @@
 
     if ( instance_index > 0 )
     {
-      FT_Memory     memory = face->root.memory;
-      SFNT_Service  sfnt   = (SFNT_Service)face->sfnt;
+      SFNT_Service  sfnt = (SFNT_Service)ttface->sfnt;
 
       FT_Var_Named_Style*  named_style;
       FT_String*           style_name;
@@ -3346,40 +3378,89 @@
 
       named_style = mmvar->namedstyle + instance_index - 1;
 
-      error = sfnt->get_name( face,
+      error = sfnt->get_name( ttface,
                               (FT_UShort)named_style->strid,
                               &style_name );
       if ( error )
         goto Exit;
 
       /* set (or replace) style name */
-      FT_FREE( face->root.style_name );
-      face->root.style_name = style_name;
+      FT_FREE( face->style_name );
+      face->style_name = style_name;
 
       /* finally, select the named instance */
       error = TT_Set_Var_Design( face,
                                  mmvar->num_axis,
                                  named_style->coords );
-      if ( error )
-      {
-        /* internal error code -1 means `no change' */
-        if ( error == -1 )
-          error = FT_Err_Ok;
-        goto Exit;
-      }
     }
     else
+    {
+      /* restore non-VF style name */
+      FT_FREE( face->style_name );
+      if ( FT_STRDUP( face->style_name, ttface->non_var_style_name ) )
+        goto Exit;
       error = TT_Set_Var_Design( face, 0, NULL );
-
-    face->root.face_index  = ( instance_index << 16 )             |
-                             ( face->root.face_index & 0xFFFFL );
-    face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
+    }
 
   Exit:
     return error;
   }
 
 
+  /**************************************************************************
+   *
+   * @Function:
+   *   TT_Get_Default_Named_Instance
+   *
+   * @Description:
+   *   Get the default named instance.
+   *
+   * @Input:
+   *   face ::
+   *     A handle to the source face.
+   *
+   * @Output:
+   *   instance_index ::
+   *     The default named instance index.
+   *
+   * @Return:
+   *   FreeType error code.  0~means success.
+   */
+  FT_LOCAL_DEF( FT_Error )
+  TT_Get_Default_Named_Instance( FT_Face   face,
+                                 FT_UInt  *instance_index )
+  {
+    TT_Face   ttface = (TT_Face)face;
+    FT_Error  error  = FT_Err_Ok;
+
+
+    if ( !ttface->blend )
+    {
+      if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
+        goto Exit;
+    }
+
+    *instance_index = ttface->var_default_named_instance;
+
+  Exit:
+    return error;
+  }
+
+
+  /* This function triggers (lazy) recomputation of the `postscript_name` */
+  /* field in `TT_Face`.                                                  */
+
+  FT_LOCAL_DEF( void )
+  tt_construct_ps_name( FT_Face  face )
+  {
+    TT_Face    ttface = (TT_Face)face;
+    FT_Memory  memory = FT_FACE_MEMORY( face );
+
+
+    FT_FREE( ttface->postscript_name );
+  }
+
+
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -4412,22 +4493,25 @@
    *   the MM machinery in case it isn't loaded yet.
    */
   FT_LOCAL_DEF( FT_Error )
-  tt_get_var_blend( TT_Face      face,
+  tt_get_var_blend( FT_Face      face,             /* TT_Face */
                     FT_UInt     *num_coords,
                     FT_Fixed*   *coords,
                     FT_Fixed*   *normalizedcoords,
                     FT_MM_Var*  *mm_var )
   {
-    if ( face->blend )
+    TT_Face  ttface = (TT_Face)face;
+
+
+    if ( ttface->blend )
     {
       if ( num_coords )
-        *num_coords       = face->blend->num_axis;
+        *num_coords       = ttface->blend->num_axis;
       if ( coords )
-        *coords           = face->blend->coords;
+        *coords           = ttface->blend->coords;
       if ( normalizedcoords )
-        *normalizedcoords = face->blend->normalizedcoords;
+        *normalizedcoords = ttface->blend->normalizedcoords;
       if ( mm_var )
-        *mm_var           = face->blend->mmvar;
+        *mm_var           = ttface->blend->mmvar;
     }
     else
     {
@@ -4444,7 +4528,7 @@
 
 
   FT_LOCAL_DEF( void )
-  tt_var_done_item_variation_store( TT_Face          face,
+  tt_var_done_item_variation_store( FT_Face          face,
                                     GX_ItemVarStore  itemStore )
   {
     FT_Memory  memory = FT_FACE_MEMORY( face );
@@ -4473,7 +4557,7 @@
 
 
   FT_LOCAL_DEF( void )
-  tt_var_done_delta_set_index_map( TT_Face            face,
+  tt_var_done_delta_set_index_map( FT_Face            face,
                                    GX_DeltaSetIdxMap  deltaSetIdxMap )
   {
     FT_Memory  memory = FT_FACE_MEMORY( face );
@@ -4493,10 +4577,11 @@
    *   Free the blend internal data structure.
    */
   FT_LOCAL_DEF( void )
-  tt_done_blend( TT_Face  face )
+  tt_done_blend( FT_Face  face )
   {
+    TT_Face    ttface = (TT_Face)face;
     FT_Memory  memory = FT_FACE_MEMORY( face );
-    GX_Blend   blend  = face->blend;
+    GX_Blend   blend  = ttface->blend;
 
 
     if ( blend )
@@ -4568,7 +4653,7 @@
 #else /* !TT_CONFIG_OPTION_GX_VAR_SUPPORT */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _tt_gxvar_dummy;
+  typedef int  tt_gxvar_dummy_;
 
 #endif /* !TT_CONFIG_OPTION_GX_VAR_SUPPORT */
 
diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h
index 4fec980..e3da6d1 100644
--- a/src/truetype/ttgxvar.h
+++ b/src/truetype/ttgxvar.h
@@ -347,34 +347,41 @@
 
 
   FT_LOCAL( FT_Error )
-  TT_Set_MM_Blend( TT_Face    face,
+  TT_Set_MM_Blend( FT_Face    face,
                    FT_UInt    num_coords,
                    FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
-  TT_Get_MM_Blend( TT_Face    face,
+  TT_Get_MM_Blend( FT_Face    face,
                    FT_UInt    num_coords,
                    FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
-  TT_Set_Var_Design( TT_Face    face,
+  TT_Set_Var_Design( FT_Face    face,
                      FT_UInt    num_coords,
                      FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
-  TT_Get_MM_Var( TT_Face      face,
+  TT_Get_MM_Var( FT_Face      face,
                  FT_MM_Var*  *master );
 
   FT_LOCAL( FT_Error )
-  TT_Get_Var_Design( TT_Face    face,
+  TT_Get_Var_Design( FT_Face    face,
                      FT_UInt    num_coords,
                      FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
-  TT_Set_Named_Instance( TT_Face  face,
+  TT_Set_Named_Instance( FT_Face  face,
                          FT_UInt  instance_index );
 
   FT_LOCAL( FT_Error )
+  TT_Get_Default_Named_Instance( FT_Face   face,
+                                 FT_UInt  *instance_index );
+
+  FT_LOCAL( void )
+  tt_construct_ps_name( FT_Face  face );
+
+  FT_LOCAL( FT_Error )
   tt_face_vary_cvt( TT_Face    face,
                     FT_Stream  stream );
 
@@ -385,55 +392,54 @@
                               FT_Vector*   unrounded );
 
   FT_LOCAL( FT_Error )
-  tt_hadvance_adjust( TT_Face  face,
+  tt_hadvance_adjust( FT_Face  face,
                       FT_UInt  gindex,
                       FT_Int  *adelta );
 
   FT_LOCAL( FT_Error )
-  tt_vadvance_adjust( TT_Face  face,
+  tt_vadvance_adjust( FT_Face  face,
                       FT_UInt  gindex,
                       FT_Int  *adelta );
 
   FT_LOCAL( void )
-  tt_apply_mvar( TT_Face  face );
-
+  tt_apply_mvar( FT_Face  face );
 
   FT_LOCAL( FT_Error )
-  tt_var_load_item_variation_store( TT_Face          face,
+  tt_var_load_item_variation_store( FT_Face          face,
                                     FT_ULong         offset,
                                     GX_ItemVarStore  itemStore );
 
   FT_LOCAL( FT_Error )
-  tt_var_load_delta_set_index_mapping( TT_Face            face,
+  tt_var_load_delta_set_index_mapping( FT_Face            face,
                                        FT_ULong           offset,
                                        GX_DeltaSetIdxMap  map,
                                        GX_ItemVarStore    itemStore,
                                        FT_ULong           table_len );
 
   FT_LOCAL( FT_ItemVarDelta )
-  tt_var_get_item_delta( TT_Face          face,
+  tt_var_get_item_delta( FT_Face          face,
                          GX_ItemVarStore  itemStore,
                          FT_UInt          outerIndex,
                          FT_UInt          innerIndex );
 
   FT_LOCAL( void )
-  tt_var_done_item_variation_store( TT_Face          face,
+  tt_var_done_item_variation_store( FT_Face          face,
                                     GX_ItemVarStore  itemStore );
 
   FT_LOCAL( void )
-  tt_var_done_delta_set_index_map( TT_Face            face,
+  tt_var_done_delta_set_index_map( FT_Face            face,
                                    GX_DeltaSetIdxMap  deltaSetIdxMap );
 
 
   FT_LOCAL( FT_Error )
-  tt_get_var_blend( TT_Face      face,
+  tt_get_var_blend( FT_Face      face,
                     FT_UInt     *num_coords,
                     FT_Fixed*   *coords,
                     FT_Fixed*   *normalizedcoords,
                     FT_MM_Var*  *mm_var );
 
   FT_LOCAL( void )
-  tt_done_blend( TT_Face  face );
+  tt_done_blend( FT_Face  face );
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
 
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index 4fcfaa3..79df455 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -29,7 +29,6 @@
 
 #include "ttinterp.h"
 #include "tterrors.h"
-#include "ttsubpix.h"
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 #include "ttgxvar.h"
 #endif
@@ -52,12 +51,6 @@
           ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
             TT_INTERPRETER_VERSION_35 )
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-#define SUBPIXEL_HINTING_INFINALITY                                          \
-          ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
-            TT_INTERPRETER_VERSION_38 )
-#endif
-
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
 #define SUBPIXEL_HINTING_MINIMAL                                             \
           ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
@@ -278,57 +271,6 @@
   /**************************************************************************
    *
    * @Function:
-   *   Update_Max
-   *
-   * @Description:
-   *   Checks the size of a buffer and reallocates it if necessary.
-   *
-   * @Input:
-   *   memory ::
-   *     A handle to the parent memory object.
-   *
-   *   multiplier ::
-   *     The size in bytes of each element in the buffer.
-   *
-   *   new_max ::
-   *     The new capacity (size) of the buffer.
-   *
-   * @InOut:
-   *   size ::
-   *     The address of the buffer's current size expressed
-   *     in elements.
-   *
-   *   buff ::
-   *     The address of the buffer base pointer.
-   *
-   * @Return:
-   *   FreeType error code.  0 means success.
-   */
-  FT_LOCAL_DEF( FT_Error )
-  Update_Max( FT_Memory  memory,
-              FT_ULong*  size,
-              FT_ULong   multiplier,
-              void*      _pbuff,
-              FT_ULong   new_max )
-  {
-    FT_Error  error;
-    void**    pbuff = (void**)_pbuff;
-
-
-    if ( *size < new_max )
-    {
-      if ( FT_QREALLOC( *pbuff, *size * multiplier, new_max * multiplier ) )
-        return error;
-      *size = new_max;
-    }
-
-    return FT_Err_Ok;
-  }
-
-
-  /**************************************************************************
-   *
-   * @Function:
    *   TT_Load_Context
    *
    * @Description:
@@ -359,9 +301,9 @@
                    TT_Size         size )
   {
     FT_Int          i;
-    FT_ULong        tmp;
     TT_MaxProfile*  maxp;
     FT_Error        error;
+    FT_Memory       memory = exec->memory;
 
 
     exec->face = face;
@@ -406,25 +348,15 @@
 
     /* XXX: We reserve a little more elements on the stack to deal safely */
     /*      with broken fonts like arialbs, courbs, timesbs, etc.         */
-    tmp = (FT_ULong)exec->stackSize;
-    error = Update_Max( exec->memory,
-                        &tmp,
-                        sizeof ( FT_F26Dot6 ),
-                        (void*)&exec->stack,
-                        maxp->maxStackElements + 32 );
-    exec->stackSize = (FT_Long)tmp;
-    if ( error )
+    if ( FT_QRENEW_ARRAY( exec->stack,
+                          exec->stackSize,
+                          maxp->maxStackElements + 32 ) )
       return error;
+    exec->stackSize = maxp->maxStackElements + 32;
 
-    tmp = (FT_ULong)exec->glyphSize;
-    error = Update_Max( exec->memory,
-                        &tmp,
-                        sizeof ( FT_Byte ),
-                        (void*)&exec->glyphIns,
-                        maxp->maxSizeOfInstructions );
-    exec->glyphSize = (FT_UInt)tmp;
-    if ( error )
-      return error;
+    /* free previous glyph code range */
+    FT_FREE( exec->glyphIns );
+    exec->glyphSize = 0;
 
     exec->pts.n_points   = 0;
     exec->pts.n_contours = 0;
@@ -1530,14 +1462,16 @@
     if ( exc->iniRange == tt_coderange_glyph &&
          exc->cvt != exc->glyfCvt            )
     {
-      exc->error = Update_Max( exc->memory,
-                               &exc->glyfCvtSize,
-                               sizeof ( FT_Long ),
-                               (void*)&exc->glyfCvt,
-                               exc->cvtSize );
-      if ( exc->error )
+      FT_Memory  memory = exc->memory;
+      FT_Error   error;
+
+
+      FT_MEM_QRENEW_ARRAY( exc->glyfCvt, exc->glyfCvtSize, exc->cvtSize );
+      exc->error = error;
+      if ( error )
         return;
 
+      exc->glyfCvtSize = exc->cvtSize;
       FT_ARRAY_COPY( exc->glyfCvt, exc->cvt, exc->glyfCvtSize );
       exc->cvt = exc->glyfCvt;
     }
@@ -1744,17 +1678,6 @@
 
     if ( v != 0 )
     {
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY                            &&
-           ( !exc->ignore_x_mode                                ||
-             ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
-        zone->cur[point].x = ADD_LONG( zone->cur[point].x,
-                                       FT_MulDiv( distance,
-                                                  v,
-                                                  exc->F_dot_P ) );
-      else
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
       /* Exception to the post-IUP curfew: Allow the x component of */
       /* diagonal moves, but only post-IUP.  DejaVu tries to adjust */
@@ -1860,12 +1783,6 @@
                  FT_UShort       point,
                  FT_F26Dot6      distance )
   {
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY && !exc->ignore_x_mode )
-      zone->cur[point].x = ADD_LONG( zone->cur[point].x, distance );
-    else
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility )
       zone->cur[point].x = ADD_LONG( zone->cur[point].x, distance );
@@ -3069,28 +2986,7 @@
         args[0] = 0;
     }
     else
-    {
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      /* subpixel hinting - avoid Typeman Dstroke and */
-      /* IStroke and Vacuform rounds                  */
-      if ( SUBPIXEL_HINTING_INFINALITY                 &&
-           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
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-        args[0] = exc->storage[I];
-    }
+      args[0] = exc->storage[I];
   }
 
 
@@ -3117,18 +3013,18 @@
       if ( exc->iniRange == tt_coderange_glyph &&
            exc->storage != exc->glyfStorage    )
       {
-        FT_ULong  tmp = (FT_ULong)exc->glyfStoreSize;
+        FT_Memory  memory = exc->memory;
+        FT_Error   error;
 
 
-        exc->error = Update_Max( exc->memory,
-                                 &tmp,
-                                 sizeof ( FT_Long ),
-                                 (void*)&exc->glyfStorage,
-                                 exc->storeSize );
-        exc->glyfStoreSize = (FT_UShort)tmp;
-        if ( exc->error )
+        FT_MEM_QRENEW_ARRAY( exc->glyfStorage,
+                             exc->glyfStoreSize,
+                             exc->storeSize );
+        exc->error  = error;
+        if ( error )
           return;
 
+        exc->glyfStoreSize = exc->storeSize;
         FT_ARRAY_COPY( exc->glyfStorage, exc->storage, exc->glyfStoreSize );
         exc->storage = exc->glyfStorage;
       }
@@ -3604,106 +3500,6 @@
     TT_DefRecord*  rec;
     TT_DefRecord*  limit;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    /* arguments to opcodes are skipped by `SKIP_Code' */
-    FT_Byte    opcode_pattern[9][12] = {
-                 /* #0 inline delta function 1 */
-                 {
-                   0x4B, /* PPEM    */
-                   0x53, /* GTEQ    */
-                   0x23, /* SWAP    */
-                   0x4B, /* PPEM    */
-                   0x51, /* LTEQ    */
-                   0x5A, /* AND     */
-                   0x58, /* IF      */
-                   0x38, /*   SHPIX */
-                   0x1B, /* ELSE    */
-                   0x21, /*   POP   */
-                   0x21, /*   POP   */
-                   0x59  /* EIF     */
-                 },
-                 /* #1 inline delta function 2 */
-                 {
-                   0x4B, /* PPEM    */
-                   0x54, /* EQ      */
-                   0x58, /* IF      */
-                   0x38, /*   SHPIX */
-                   0x1B, /* ELSE    */
-                   0x21, /*   POP   */
-                   0x21, /*   POP   */
-                   0x59  /* EIF     */
-                 },
-                 /* #2 diagonal stroke function */
-                 {
-                   0x20, /* DUP     */
-                   0x20, /* DUP     */
-                   0xB0, /* PUSHB_1 */
-                         /*   1     */
-                   0x60, /* ADD     */
-                   0x46, /* GC_cur  */
-                   0xB0, /* PUSHB_1 */
-                         /*   64    */
-                   0x23, /* SWAP    */
-                   0x42  /* WS      */
-                 },
-                 /* #3 VacuFormRound function */
-                 {
-                   0x45, /* RCVT    */
-                   0x23, /* SWAP    */
-                   0x46, /* GC_cur  */
-                   0x60, /* ADD     */
-                   0x20, /* DUP     */
-                   0xB0  /* PUSHB_1 */
-                         /*   38    */
-                 },
-                 /* #4 TTFautohint bytecode (old) */
-                 {
-                   0x20, /* DUP     */
-                   0x64, /* ABS     */
-                   0xB0, /* PUSHB_1 */
-                         /*   32    */
-                   0x60, /* ADD     */
-                   0x66, /* FLOOR   */
-                   0x23, /* SWAP    */
-                   0xB0  /* PUSHB_1 */
-                 },
-                 /* #5 spacing function 1 */
-                 {
-                   0x01, /* SVTCA_x */
-                   0xB0, /* PUSHB_1 */
-                         /*   24    */
-                   0x43, /* RS      */
-                   0x58  /* IF      */
-                 },
-                 /* #6 spacing function 2 */
-                 {
-                   0x01, /* SVTCA_x */
-                   0x18, /* RTG     */
-                   0xB0, /* PUSHB_1 */
-                         /*   24    */
-                   0x43, /* RS      */
-                   0x58  /* IF      */
-                 },
-                 /* #7 TypeMan Talk DiagEndCtrl function */
-                 {
-                   0x01, /* SVTCA_x */
-                   0x20, /* DUP     */
-                   0xB0, /* PUSHB_1 */
-                         /*   3     */
-                   0x25, /* CINDEX  */
-                 },
-                 /* #8 TypeMan Talk Align */
-                 {
-                   0x06, /* SPVTL   */
-                   0x7D, /* RDTG    */
-                 },
-               };
-    FT_UShort  opcode_patterns   = 9;
-    FT_UShort  opcode_pointer[9] = {  0, 0, 0, 0, 0, 0, 0, 0, 0 };
-    FT_UShort  opcode_size[9]    = { 12, 8, 8, 6, 7, 4, 5, 4, 2 };
-    FT_UShort  i;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
 
     /* FDEF is only allowed in `prep' or `fpgm' */
     if ( exc->iniRange == tt_coderange_glyph )
@@ -3748,136 +3544,15 @@
     rec->opc            = (FT_UInt16)n;
     rec->start          = exc->IP + 1;
     rec->active         = TRUE;
-    rec->inline_delta   = FALSE;
-    rec->sph_fdef_flags = 0x0000;
 
     if ( n > exc->maxFunc )
       exc->maxFunc = (FT_UInt16)n;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    /* We don't know for sure these are typeman functions, */
-    /* however they are only active when RS 22 is called   */
-    if ( n >= 64 && n <= 66 )
-      rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES;
-#endif
-
     /* Now skip the whole function definition. */
     /* We don't allow nested IDEFS & FDEFs.    */
 
     while ( SkipCode( exc ) == SUCCESS )
     {
-
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-      if ( SUBPIXEL_HINTING_INFINALITY )
-      {
-        for ( i = 0; i < opcode_patterns; 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_TRACE6(( "sph: Function %d, opcode ptrn: %ld, %s %s\n",
-                          i, n,
-                          exc->face->root.family_name,
-                          exc->face->root.style_name ));
-
-              switch ( i )
-              {
-              case 0:
-                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;
-                exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2;
-                break;
-
-              case 2:
-                switch ( n )
-                {
-                  /* needs to be implemented still */
-                case 58:
-                  rec->sph_fdef_flags             |= SPH_FDEF_DIAGONAL_STROKE;
-                  exc->face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE;
-                }
-                break;
-
-              case 3:
-                switch ( n )
-                {
-                case 0:
-                  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;
-                exc->face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1;
-                break;
-
-              case 5:
-                switch ( n )
-                {
-                case 0:
-                case 1:
-                case 2:
-                case 4:
-                case 7:
-                case 8:
-                  rec->sph_fdef_flags             |= SPH_FDEF_SPACING_1;
-                  exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_1;
-                }
-                break;
-
-              case 6:
-                switch ( n )
-                {
-                case 0:
-                case 1:
-                case 2:
-                case 4:
-                case 7:
-                case 8:
-                  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;
-                 exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
-                 break;
-
-               case 8:
-#if 0
-                 rec->sph_fdef_flags             |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
-                 exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
-#endif
-                 break;
-              }
-              opcode_pointer[i] = 0;
-            }
-          }
-
-          else
-            opcode_pointer[i] = 0;
-        }
-
-        /* Set sph_compatibility_mode only when deltas are detected */
-        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_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       switch ( exc->opcode )
       {
       case 0x89:    /* IDEF */
@@ -3905,10 +3580,6 @@
     TT_CallRec*  pRec;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    exc->sph_in_func_flags = 0x0000;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     if ( exc->callTop <= 0 )     /* We encountered an ENDF without a call */
     {
       exc->error = FT_THROW( ENDF_In_Exec_Stream );
@@ -3996,17 +3667,6 @@
     if ( !def->active )
       goto Fail;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY                                    &&
-         exc->ignore_x_mode                                             &&
-         ( ( exc->iup_called                                        &&
-             ( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
-           ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 )        ) )
-      goto Fail;
-    else
-      exc->sph_in_func_flags = def->sph_fdef_flags;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     /* check the call stack */
     if ( exc->callTop >= exc->callSize )
     {
@@ -4084,15 +3744,6 @@
     if ( !def->active )
       goto Fail;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY                         &&
-         exc->ignore_x_mode                                  &&
-         ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
-      goto Fail;
-    else
-      exc->sph_in_func_flags = def->sph_fdef_flags;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     /* check stack */
     if ( exc->callTop >= exc->callSize )
     {
@@ -4998,14 +4649,6 @@
       }
     }
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
-    if ( SUBPIXEL_HINTING_INFINALITY         &&
-         exc->ignore_x_mode                  &&
-         ( D < 0 ? NEG_LONG( D ) : D ) == 64 )
-      D += 1;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     args[0] = D;
   }
 
@@ -5267,13 +4910,6 @@
     /* except to change the subpixel flags temporarily */
     else if ( exc->iniRange == tt_coderange_glyph && K == 3 )
     {
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      /* INSTCTRL modifying flag 3 also has an effect */
-      /* outside of the CVT program                   */
-      if ( SUBPIXEL_HINTING_INFINALITY )
-        exc->ignore_x_mode = !FT_BOOL( L == 4 );
-#endif
-
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
       /* Native ClearType fonts sign a waiver that turns off all backward  */
       /* compatibility hacks and lets them program points to the grid like */
@@ -5605,12 +5241,6 @@
         }
       }
       else
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      /* doesn't follow Cleartype spec but produces better result */
-      if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode )
-        Move_Zp2_Point( exc, point, 0, dy, TRUE );
-      else
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
         Move_Zp2_Point( exc, point, dx, dy, TRUE );
 
       exc->GS.loop--;
@@ -5771,76 +5401,6 @@
         }
       }
       else
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY &&
-           exc->ignore_x_mode          )
-      {
-        FT_Int  B1, B2;
-
-
-        /*  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               */
-
-        /* save point for later comparison */
-        B1 = exc->zp2.cur[point].y;
-
-        if ( exc->face->sph_compatibility_mode )
-        {
-          if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
-            dy = FT_PIX_ROUND( B1 + dy ) - B1;
-
-          /* skip post-iup deltas */
-          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 ( !( 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 ( exc->GS.freeVector.y != 0 )
-          {
-            B2 = exc->zp2.cur[point].y;
-
-            /* reverse any disallowed moves */
-            if ( ( B1 & 63 ) == 0 &&
-                 ( B2 & 63 ) != 0 &&
-                 B1 != B2         )
-              Move_Zp2_Point( exc, point, 0, NEG_LONG( dy ), TRUE );
-          }
-        }
-        else if ( exc->GS.freeVector.y != 0 )
-        {
-          Move_Zp2_Point( exc, point, dx, dy, TRUE );
-
-          /* save new point */
-          B2 = exc->zp2.cur[point].y;
-
-          /* reverse any disallowed moves */
-          if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
-               ( B1 & 63 ) != 0                                           &&
-               ( B2 & 63 ) != 0                                           &&
-               B1 != B2                                                   )
-            Move_Zp2_Point( exc,
-                            point,
-                            NEG_LONG( dx ),
-                            NEG_LONG( dy ),
-                            TRUE );
-        }
-        else if ( exc->sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
-          Move_Zp2_Point( exc, point, dx, dy, TRUE );
-      }
-      else
-#endif
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
       if ( SUBPIXEL_HINTING_MINIMAL    &&
            exc->backward_compatibility )
@@ -5860,9 +5420,6 @@
 #endif
         Move_Zp2_Point( exc, point, dx, dy, TRUE );
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    Skip:
-#endif
       exc->GS.loop--;
     }
 
@@ -5907,28 +5464,6 @@
 
     distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    /* subpixel hinting - make MSIRP respect CVT cut-in; */
-    if ( SUBPIXEL_HINTING_INFINALITY &&
-         exc->ignore_x_mode          &&
-         exc->GS.freeVector.x != 0   )
-    {
-      FT_F26Dot6  control_value_cutin = exc->GS.control_value_cutin;
-      FT_F26Dot6  delta;
-
-
-      if ( !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
-        control_value_cutin = 0;
-
-      delta = SUB_LONG( distance, args[1] );
-      if ( delta < 0 )
-        delta = NEG_LONG( delta );
-
-      if ( delta >= control_value_cutin )
-        distance = args[1];
-    }
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     exc->func_move( exc,
                     &exc->zp1,
                     point,
@@ -5969,14 +5504,7 @@
     if ( ( exc->opcode & 1 ) != 0 )
     {
       cur_dist = FAST_PROJECT( &exc->zp0.cur[point] );
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY &&
-           exc->ignore_x_mode          &&
-           exc->GS.freeVector.x != 0   )
-        distance = SUB_LONG( Round_None( exc, cur_dist, 3 ), cur_dist );
-      else
-#endif
-        distance = SUB_LONG( exc->func_round( exc, cur_dist, 3 ), cur_dist );
+      distance = SUB_LONG( exc->func_round( exc, cur_dist, 3 ), cur_dist );
     }
     else
       distance = 0;
@@ -6039,27 +5567,12 @@
 
     if ( exc->GS.gep0 == 0 )   /* If in twilight zone */
     {
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */
-      /* Determined via experimentation and may be incorrect...         */
-      if ( !( SUBPIXEL_HINTING_INFINALITY           &&
-              ( exc->ignore_x_mode                &&
-                exc->face->sph_compatibility_mode ) ) )
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-        exc->zp0.org[point].x = TT_MulFix14( distance,
+      exc->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_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY                    &&
-         exc->ignore_x_mode                             &&
-         ( exc->sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
-         distance > 0                                   &&
-         exc->GS.freeVector.y != 0                      )
-      distance = 0;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     org_dist = FAST_PROJECT( &exc->zp0.cur[point] );
 
@@ -6069,15 +5582,6 @@
       FT_F26Dot6  delta;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY                        &&
-           exc->ignore_x_mode                                 &&
-           exc->GS.freeVector.x != 0                          &&
-           exc->GS.freeVector.y == 0                          &&
-           !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
-        control_value_cutin = 0;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       delta = SUB_LONG( distance, org_dist );
       if ( delta < 0 )
         delta = NEG_LONG( delta );
@@ -6085,14 +5589,7 @@
       if ( delta > control_value_cutin )
         distance = org_dist;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY &&
-           exc->ignore_x_mode          &&
-           exc->GS.freeVector.x != 0   )
-        distance = Round_None( exc, distance, 3 );
-      else
-#endif
-        distance = exc->func_round( exc, distance, 3 );
+      distance = exc->func_round( exc, distance, 3 );
     }
 
     exc->func_move( exc, &exc->zp0, point, SUB_LONG( distance, org_dist ) );
@@ -6185,14 +5682,7 @@
 
     if ( ( exc->opcode & 4 ) != 0 )
     {
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY &&
-           exc->ignore_x_mode          &&
-           exc->GS.freeVector.x != 0   )
-        distance = Round_None( exc, org_dist, exc->opcode & 3 );
-      else
-#endif
-        distance = exc->func_round( exc, org_dist, exc->opcode & 3 );
+      distance = exc->func_round( exc, org_dist, exc->opcode & 3 );
     }
     else
       distance = Round_None( exc, org_dist, exc->opcode & 3 );
@@ -6204,14 +5694,6 @@
       FT_F26Dot6  minimum_distance = exc->GS.minimum_distance;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY                        &&
-           exc->ignore_x_mode                                 &&
-           exc->GS.freeVector.x != 0                          &&
-           !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
-        minimum_distance = 0;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       if ( org_dist >= 0 )
       {
         if ( distance < minimum_distance )
@@ -6354,41 +5836,7 @@
       distance = exc->func_round( exc, cvt_dist, exc->opcode & 3 );
     }
     else
-    {
-
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      /* do cvt cut-in always in MIRP for sph */
-      if ( SUBPIXEL_HINTING_INFINALITY  &&
-           exc->ignore_x_mode           &&
-           exc->GS.gep0 == exc->GS.gep1 )
-      {
-        FT_F26Dot6  control_value_cutin = exc->GS.control_value_cutin;
-
-
-        if ( exc->GS.freeVector.x != 0                          &&
-             !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
-          control_value_cutin = 0;
-
-        if ( exc->GS.freeVector.y != 0                                 &&
-             ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
-        {
-          if ( cur_dist < -64 )
-            cvt_dist -= 16;
-          else if ( cur_dist > 64 && cur_dist < 84 )
-            cvt_dist += 32;
-        }
-
-        delta = SUB_LONG( cvt_dist, org_dist );
-        if ( delta < 0 )
-          delta = NEG_LONG( delta );
-
-        if ( delta > control_value_cutin )
-          cvt_dist = org_dist;
-      }
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       distance = Round_None( exc, cvt_dist, exc->opcode & 3 );
-    }
 
     /* minimum distance test */
 
@@ -6397,14 +5845,6 @@
       FT_F26Dot6  minimum_distance    = exc->GS.minimum_distance;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY                        &&
-           exc->ignore_x_mode                                 &&
-           exc->GS.freeVector.x != 0                          &&
-           !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
-        minimum_distance = 0;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       if ( org_dist >= 0 )
       {
         if ( distance < minimum_distance )
@@ -6417,51 +5857,10 @@
       }
     }
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY &&
-         exc->ignore_x_mode          &&
-         exc->GS.freeVector.y != 0   )
-    {
-      FT_Int   B1, B2;
-
-
-      B1 = exc->zp1.cur[point].y;
-
-      /* Round moves if necessary */
-      if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
-        distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist;
-
-      if ( ( exc->opcode & 16 ) == 0                               &&
-           ( exc->opcode & 8 ) == 0                                &&
-           ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
-        distance += 64;
-
-      exc->func_move( exc,
-                      &exc->zp1,
-                      point,
-                      SUB_LONG( distance, cur_dist ) );
-
-      B2 = exc->zp1.cur[point].y;
-
-      /* Reverse move if necessary */
-      if ( ( exc->face->sph_compatibility_mode &&
-             ( B1 & 63 ) == 0                  &&
-             ( B2 & 63 ) != 0                  )                          ||
-           ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
-             ( B1 & 63 ) != 0                                           &&
-             ( B2 & 63 ) != 0                                           ) )
-        exc->func_move( exc,
-                        &exc->zp1,
-                        point,
-                        SUB_LONG( cur_dist, distance ) );
-    }
-    else
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
-      exc->func_move( exc,
-                      &exc->zp1,
-                      point,
-                      SUB_LONG( distance, cur_dist ) );
+    exc->func_move( exc,
+                    &exc->zp1,
+                    point,
+                    SUB_LONG( distance, cur_dist ) );
 
   Fail:
     exc->GS.rp1 = exc->GS.rp0;
@@ -6486,17 +5885,6 @@
     FT_F26Dot6  distance;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY                               &&
-         exc->ignore_x_mode                                        &&
-         exc->iup_called                                           &&
-         ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
-    {
-      exc->error = FT_THROW( Invalid_Reference );
-      goto Fail;
-    }
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     if ( exc->top < exc->GS.loop                  ||
          BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
     {
@@ -7055,16 +6443,6 @@
     contour = 0;
     point   = 0;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY &&
-         exc->ignore_x_mode          )
-    {
-      exc->iup_called = TRUE;
-      if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
-        return;
-    }
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     do
     {
       end_point   = exc->pts.contours[contour] - exc->pts.first_point;
@@ -7137,14 +6515,6 @@
     FT_Long    B;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY                              &&
-         exc->ignore_x_mode                                       &&
-         exc->iup_called                                          &&
-         ( exc->sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
-      goto Fail;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     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 */
@@ -7197,87 +6567,21 @@
             B++;
           B *= 1L << ( 6 - exc->GS.delta_shift );
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-          if ( SUBPIXEL_HINTING_INFINALITY )
-          {
-            /*
-             * Allow delta move if
-             *
-             * - 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 ( !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, always skipping deltas in subpixel direction.     */
-            else if ( exc->ignore_x_mode && exc->GS.freeVector.y != 0 )
-            {
-              FT_UShort  B1, B2;
-
-
-              /* save the y value of the point now; compare after move */
-              B1 = (FT_UShort)exc->zp0.cur[A].y;
-
-              /* 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 */
-              else if ( exc->face->sph_compatibility_mode                        &&
-                        !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
-              {
-                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 ( !exc->iup_called                            &&
-                     ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
-                  exc->func_move( exc, &exc->zp0, A, B );
-              }
-
-              B2 = (FT_UShort)exc->zp0.cur[A].y;
-
-              /* Reverse this move if it results in a disallowed move */
-              if ( exc->GS.freeVector.y != 0                          &&
-                   ( ( exc->face->sph_compatibility_mode          &&
-                       ( B1 & 63 ) == 0                           &&
-                       ( B2 & 63 ) != 0                           ) ||
-                     ( ( exc->sph_tweak_flags                   &
-                         SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) &&
-                       ( B1 & 63 ) != 0                           &&
-                       ( B2 & 63 ) != 0                           ) ) )
-                exc->func_move( exc, &exc->zp0, A, NEG_LONG( B ) );
-            }
-          }
-          else
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
-          {
 
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-            /* See `ttinterp.h' for details on backward compatibility */
-            /* mode.                                                  */
-            if ( SUBPIXEL_HINTING_MINIMAL    &&
-                 exc->backward_compatibility )
-            {
-              if ( !( exc->iupx_called && exc->iupy_called )              &&
-                   ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
-                     ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y )        ) )
-                exc->func_move( exc, &exc->zp0, A, B );
-            }
-            else
-#endif
+          /* See `ttinterp.h' for details on backward compatibility */
+          /* mode.                                                  */
+          if ( SUBPIXEL_HINTING_MINIMAL    &&
+               exc->backward_compatibility )
+          {
+            if ( !( exc->iupx_called && exc->iupy_called )              &&
+                 ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
+                   ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y )        ) )
               exc->func_move( exc, &exc->zp0, A, B );
           }
+          else
+#endif
+            exc->func_move( exc, &exc->zp0, A, B );
         }
       }
       else
@@ -7380,14 +6684,6 @@
    * GETINFO[]:    GET INFOrmation
    * 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( TT_ExecContext  exc,
@@ -7399,31 +6695,8 @@
 
     K = 0;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    /*********************************
-     * RASTERIZER VERSION
-     * Selector Bit:  0
-     * Return Bit(s): 0-7
-     */
-    if ( SUBPIXEL_HINTING_INFINALITY &&
-         ( args[0] & 1 ) != 0        &&
-         exc->subpixel_hinting       )
-    {
-      if ( exc->ignore_x_mode )
-      {
-        /* if in ClearType backward 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_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-      if ( ( args[0] & 1 ) != 0 )
-        K = driver->interpreter_version;
+    if ( ( args[0] & 1 ) != 0 )
+      K = driver->interpreter_version;
 
     /*********************************
      * GLYPH ROTATED
@@ -7446,8 +6719,6 @@
      * VARIATION GLYPH
      * Selector Bit:  3
      * Return Bit(s): 10
-     *
-     * XXX: UNDOCUMENTED!
      */
     if ( (args[0] & 8 ) != 0 && exc->face->blend )
       K |= 1 << 10;
@@ -7522,89 +6793,6 @@
     }
 #endif
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-    if ( SUBPIXEL_HINTING_INFINALITY                          &&
-         exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 )
-    {
-
-      if ( exc->rasterizer_version >= 37 )
-      {
-        /*********************************
-         * HINTING FOR SUBPIXEL
-         * Selector Bit:  6
-         * Return Bit(s): 13
-         */
-        if ( ( args[0] & 64 ) != 0 && exc->subpixel_hinting )
-          K |= 1 << 13;
-
-        /*********************************
-         * COMPATIBLE WIDTHS ENABLED
-         * Selector Bit:  7
-         * Return Bit(s): 14
-         *
-         * Functionality still needs to be added
-         */
-        if ( ( args[0] & 128 ) != 0 && exc->compatible_widths )
-          K |= 1 << 14;
-
-        /*********************************
-         * VERTICAL LCD SUBPIXELS?
-         * Selector Bit:  8
-         * Return Bit(s): 15
-         *
-         * Functionality still needs to be added
-         */
-        if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd )
-          K |= 1 << 15;
-
-        /*********************************
-         * HINTING FOR BGR?
-         * Selector Bit:  9
-         * Return Bit(s): 16
-         *
-         * Functionality still needs to be added
-         */
-        if ( ( args[0] & 512 ) != 0 && exc->bgr )
-          K |= 1 << 16;
-
-        if ( exc->rasterizer_version >= 38 )
-        {
-          /*********************************
-           * SUBPIXEL POSITIONED?
-           * Selector Bit:  10
-           * Return Bit(s): 17
-           *
-           * Functionality still needs to be added
-           */
-          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;
-        }
-      }
-    }
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     args[0] = K;
   }
 
@@ -7739,25 +6927,14 @@
   /* documentation is in ttinterp.h */
 
   FT_EXPORT_DEF( FT_Error )
-  TT_RunIns( TT_ExecContext  exc )
+  TT_RunIns( void*  exec )
   {
+    TT_ExecContext  exc = (TT_ExecContext)exec;
+
     FT_ULong   ins_counter = 0;  /* executed instructions counter */
     FT_ULong   num_twilight_points;
     FT_UShort  i;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    FT_Byte    opcode_pattern[1][2] = {
-                  /* #8 TypeMan Talk Align */
-                  {
-                    0x06, /* SPVTL   */
-                    0x7D, /* RDTG    */
-                  },
-                };
-    FT_UShort  opcode_patterns   = 1;
-    FT_UShort  opcode_pointer[1] = { 0 };
-    FT_UShort  opcode_size[1]    = { 1 };
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
 
     /* We restrict the number of twilight points to a reasonable,     */
     /* heuristic value to avoid slow execution of malformed bytecode. */
@@ -7835,9 +7012,6 @@
     Compute_Round( exc, (FT_Byte)exc->GS.round_state );
 
     /* These flags cancel execution of some opcodes after IUP is called */
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    exc->iup_called  = FALSE;
-#endif
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     exc->iupx_called = FALSE;
     exc->iupy_called = FALSE;
@@ -7906,7 +7080,7 @@
         /* a variable number of arguments             */
 
         /* it is the job of the application to `activate' GX handling, */
-        /* this is, calling any of the GX API functions on the current */
+        /* that is, calling any of the GX API functions on the current */
         /* font to select a variation instance                         */
         if ( exc->face->blend )
           exc->new_top = exc->args + exc->face->blend->num_axis;
@@ -7927,39 +7101,6 @@
       exc->step_ins = TRUE;
       exc->error    = FT_Err_Ok;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-      if ( SUBPIXEL_HINTING_INFINALITY )
-      {
-        for ( i = 0; i < opcode_patterns; 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_TRACE6(( "sph: opcode ptrn: %d, %s %s\n",
-                          i,
-                          exc->face->root.family_name,
-                          exc->face->root.style_name ));
-
-              switch ( i )
-              {
-              case 0:
-                break;
-              }
-              opcode_pointer[i] = 0;
-            }
-          }
-          else
-            opcode_pointer[i] = 0;
-        }
-      }
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       {
         FT_Long*  args   = exc->stack + exc->args;
         FT_Byte   opcode = exc->opcode;
@@ -8466,7 +7607,7 @@
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
         case 0x91:
           /* it is the job of the application to `activate' GX handling, */
-          /* this is, calling any of the GX API functions on the current */
+          /* that is, calling any of the GX API functions on the current */
           /* font to select a variation instance                         */
           if ( exc->face->blend )
             Ins_GETVARIATION( exc, args );
@@ -8604,7 +7745,7 @@
 #else /* !TT_USE_BYTECODE_INTERPRETER */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _tt_interp_dummy;
+  typedef int  tt_interp_dummy_;
 
 #endif /* !TT_USE_BYTECODE_INTERPRETER */
 
diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h
index c54c053..e98e258 100644
--- a/src/truetype/ttinterp.h
+++ b/src/truetype/ttinterp.h
@@ -98,48 +98,6 @@
   } TT_CallRec, *TT_CallStack;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-  /**************************************************************************
-   *
-   * These structures define rules used to tweak subpixel hinting for
-   * various fonts.  "", 0, "", NULL value indicates to match any value.
-   */
-
-#define SPH_MAX_NAME_SIZE      32
-#define SPH_MAX_CLASS_MEMBERS  100
-
-  typedef struct  SPH_TweakRule_
-  {
-    const char      family[SPH_MAX_NAME_SIZE];
-    const FT_UInt   ppem;
-    const char      style[SPH_MAX_NAME_SIZE];
-    const FT_ULong  glyph;
-
-  } SPH_TweakRule;
-
-
-  typedef struct  SPH_ScaleRule_
-  {
-    const char      family[SPH_MAX_NAME_SIZE];
-    const FT_UInt   ppem;
-    const char      style[SPH_MAX_NAME_SIZE];
-    const FT_ULong  glyph;
-    const FT_ULong  scale;
-
-  } SPH_ScaleRule;
-
-
-  typedef struct  SPH_Font_Class_
-  {
-    const char  name[SPH_MAX_NAME_SIZE];
-    const char  member[SPH_MAX_CLASS_MEMBERS][SPH_MAX_NAME_SIZE];
-
-  } SPH_Font_Class;
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
-
   /**************************************************************************
    *
    * The main structure for the interpreter which collects all necessary
@@ -399,38 +357,6 @@
     FT_Bool            grayscale_cleartype;
 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    TT_Round_Func      func_round_sphn;   /* subpixel rounding function */
-
-    FT_Bool            subpixel_hinting;  /* Using subpixel hinting?       */
-    FT_Bool            ignore_x_mode;     /* Standard rendering mode for   */
-                                          /* subpixel hinting.  On if gray */
-                                          /* or subpixel hinting is on.    */
-
-    /* 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     */
-
-    FT_Bool            iup_called;            /* IUP called for glyph?     */
-
-    FT_ULong           sph_tweak_flags;       /* flags to control          */
-                                              /* hint tweaks               */
-
-    FT_ULong           sph_in_func_flags;     /* flags to indicate if in   */
-                                              /* special functions         */
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     /* We maintain two counters (in addition to the instruction counter) */
     /* that act as loop detectors for LOOPCALL and jump opcodes with     */
     /* negative arguments.                                               */
@@ -460,14 +386,6 @@
   FT_LOCAL( void )
   TT_Clear_CodeRange( TT_ExecContext  exec,
                       FT_Int          range );
-
-
-  FT_LOCAL( FT_Error )
-  Update_Max( FT_Memory  memory,
-              FT_ULong*  size,
-              FT_ULong   multiplier,
-              void*      _pbuff,
-              FT_ULong   new_max );
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
 
@@ -536,7 +454,7 @@
    *   invoked by the TrueType debugger.
    */
   FT_EXPORT( FT_Error )
-  TT_RunIns( TT_ExecContext  exec );
+  TT_RunIns( void*  exec );
 
 
 FT_END_HEADER
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index c351e08..5b56af7 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -312,7 +312,8 @@
 #define TRICK_SFNT_IDS_NUM_FACES  31
 
     static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES]
-                                       [TRICK_SFNT_IDS_PER_FACE] = {
+                                       [TRICK_SFNT_IDS_PER_FACE] =
+    {
 
 #define TRICK_SFNT_ID_cvt   0
 #define TRICK_SFNT_ID_fpgm  1
@@ -581,7 +582,7 @@
     FT_Bool   result = FALSE;
 
     TT_Face   face = (TT_Face)ttface;
-    FT_UInt   asize;
+    FT_ULong  asize;
     FT_ULong  i;
     FT_ULong  glyph_index = 0;
     FT_UInt   count       = 0;
@@ -589,7 +590,7 @@
 
     for( i = 0; i < face->num_locations; i++ )
     {
-      tt_face_get_location( face, i, &asize );
+      tt_face_get_location( ttface, i, &asize );
       if ( asize > 0 )
       {
         count += 1;
@@ -777,7 +778,6 @@
     }
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-
     {
       FT_UInt  instance_index = (FT_UInt)face_index >> 16;
 
@@ -785,14 +785,11 @@
       if ( FT_HAS_MULTIPLE_MASTERS( ttface ) &&
            instance_index > 0                )
       {
-        error = TT_Set_Named_Instance( face, instance_index );
+        error = FT_Set_Named_Instance( ttface, instance_index );
         if ( error )
           goto Exit;
-
-        tt_apply_mvar( face );
       }
     }
-
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
 
     /* initialize standard glyph loading routines */
@@ -858,7 +855,7 @@
     face->cvt_program_size  = 0;
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-    tt_done_blend( face );
+    tt_done_blend( ttface );
     face->blend = NULL;
 #endif
   }
@@ -1484,9 +1481,6 @@
     TT_Driver  driver = (TT_Driver)ttdriver;
 
     driver->interpreter_version = TT_INTERPRETER_VERSION_35;
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    driver->interpreter_version = TT_INTERPRETER_VERSION_38;
-#endif
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     driver->interpreter_version = TT_INTERPRETER_VERSION_40;
 #endif
diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h
index d1834c0..40eb37b 100644
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -162,8 +162,6 @@
     FT_Long   end;            /* where does it end?                     */
     FT_UInt   opc;            /* function #, or instruction code        */
     FT_Bool   active;         /* is it active?                          */
-    FT_Bool   inline_delta;   /* is function that defines inline delta? */
-    FT_ULong  sph_fdef_flags; /* flags to identify special functions    */
 
   } TT_DefRecord, *TT_DefArray;
 
diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c
index e08bf30..54a64c7 100644
--- a/src/truetype/ttpload.c
+++ b/src/truetype/ttpload.c
@@ -180,10 +180,11 @@
 
 
   FT_LOCAL_DEF( FT_ULong )
-  tt_face_get_location( TT_Face   face,
-                        FT_UInt   gindex,
-                        FT_UInt  *asize )
+  tt_face_get_location( FT_Face    face,   /* TT_Face */
+                        FT_UInt    gindex,
+                        FT_ULong  *asize )
   {
+    TT_Face   ttface = (TT_Face)face;
     FT_ULong  pos1, pos2;
     FT_Byte*  p;
     FT_Byte*  p_limit;
@@ -191,12 +192,12 @@
 
     pos1 = pos2 = 0;
 
-    if ( gindex < face->num_locations )
+    if ( gindex < ttface->num_locations )
     {
-      if ( face->header.Index_To_Loc_Format != 0 )
+      if ( ttface->header.Index_To_Loc_Format != 0 )
       {
-        p       = face->glyph_locations + gindex * 4;
-        p_limit = face->glyph_locations + face->num_locations * 4;
+        p       = ttface->glyph_locations + gindex * 4;
+        p_limit = ttface->glyph_locations + ttface->num_locations * 4;
 
         pos1 = FT_NEXT_ULONG( p );
         pos2 = pos1;
@@ -206,8 +207,8 @@
       }
       else
       {
-        p       = face->glyph_locations + gindex * 2;
-        p_limit = face->glyph_locations + face->num_locations * 2;
+        p       = ttface->glyph_locations + gindex * 2;
+        p_limit = ttface->glyph_locations + ttface->num_locations * 2;
 
         pos1 = FT_NEXT_USHORT( p );
         pos2 = pos1;
@@ -221,30 +222,30 @@
     }
 
     /* Check broken location data. */
-    if ( pos1 > face->glyf_len )
+    if ( pos1 > ttface->glyf_len )
     {
       FT_TRACE1(( "tt_face_get_location:"
                   " too large offset (0x%08lx) found for glyph index %d,\n",
                   pos1, gindex ));
       FT_TRACE1(( "                     "
                   " exceeding the end of `glyf' table (0x%08lx)\n",
-                  face->glyf_len ));
+                  ttface->glyf_len ));
       *asize = 0;
       return 0;
     }
 
-    if ( pos2 > face->glyf_len )
+    if ( pos2 > ttface->glyf_len )
     {
       /* We try to sanitize the last `loca' entry. */
-      if ( gindex == face->num_locations - 2 )
+      if ( gindex == ttface->num_locations - 2 )
       {
         FT_TRACE1(( "tt_face_get_location:"
                     " too large size (%ld bytes) found for glyph index %d,\n",
                     pos2 - pos1, gindex ));
         FT_TRACE1(( "                     "
                     " truncating at the end of `glyf' table to %ld bytes\n",
-                    face->glyf_len - pos1 ));
-        pos2 = face->glyf_len;
+                    ttface->glyf_len - pos1 ));
+        pos2 = ttface->glyf_len;
       }
       else
       {
@@ -253,7 +254,7 @@
                     pos2, gindex + 1 ));
         FT_TRACE1(( "                     "
                     " exceeding the end of `glyf' table (0x%08lx)\n",
-                    face->glyf_len ));
+                    ttface->glyf_len ));
         *asize = 0;
         return 0;
       }
@@ -268,9 +269,9 @@
     /* We get (intentionally) a wrong, non-zero result in case the  */
     /* `glyf' table is missing.                                     */
     if ( pos2 >= pos1 )
-      *asize = (FT_UInt)( pos2 - pos1 );
+      *asize = (FT_ULong)( pos2 - pos1 );
     else
-      *asize = (FT_UInt)( face->glyf_len - pos1 );
+      *asize = (FT_ULong)( ttface->glyf_len - pos1 );
 
     return pos1;
   }
diff --git a/src/truetype/ttpload.h b/src/truetype/ttpload.h
index 939e02f..ed229fa 100644
--- a/src/truetype/ttpload.h
+++ b/src/truetype/ttpload.h
@@ -31,9 +31,9 @@
                      FT_Stream  stream );
 
   FT_LOCAL( FT_ULong )
-  tt_face_get_location( TT_Face   face,
-                        FT_UInt   gindex,
-                        FT_UInt  *asize );
+  tt_face_get_location( FT_Face    face,
+                        FT_UInt    gindex,
+                        FT_ULong  *asize );
 
   FT_LOCAL( void )
   tt_face_done_loca( TT_Face  face );
diff --git a/src/truetype/ttsubpix.c b/src/truetype/ttsubpix.c
deleted file mode 100644
index d811bee..0000000
--- a/src/truetype/ttsubpix.c
+++ /dev/null
@@ -1,1013 +0,0 @@
-/****************************************************************************
- *
- * ttsubpix.c
- *
- *   TrueType Subpixel Hinting.
- *
- * Copyright (C) 2010-2023 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 <freetype/internal/ftdebug.h>
-#include <freetype/internal/ftcalc.h>
-#include <freetype/internal/ftstream.h>
-#include <freetype/internal/sfnt.h>
-#include <freetype/tttags.h>
-#include <freetype/ftoutln.h>
-#include <freetype/ftdriver.h>
-
-#include "ttsubpix.h"
-
-
-#if defined( TT_USE_BYTECODE_INTERPRETER )            && \
-    defined( TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY )
-
-  /**************************************************************************
-   *
-   * These rules affect how the TT Interpreter does hinting, with the
-   * goal of doing subpixel hinting by (in general) ignoring x moves.
-   * Some of these rules are fixes that go above and beyond the
-   * stated techniques in the MS whitepaper on Cleartype, due to
-   * artifacts in many glyphs.  So, these rules make some glyphs render
-   * better than they do in the MS rasterizer.
-   *
-   * "" string or 0 int/char indicates to apply to all glyphs.
-   * "-" used as dummy placeholders, but any non-matching string works.
-   *
-   * Some of this could arguably be implemented in fontconfig, however:
-   *
-   * - Fontconfig can't set things on a glyph-by-glyph basis.
-   * - The tweaks that happen here are very low-level, from an average
-   *   user's point of view and are best implemented in the hinter.
-   *
-   * The goal is to make the subpixel hinting techniques as generalized
-   * as possible across all fonts to prevent the need for extra rules such
-   * as these.
-   *
-   * The rule structure is designed so that entirely new rules can easily
-   * be added when a new compatibility feature is discovered.
-   *
-   * The rule structures could also use some enhancement to handle ranges.
-   *
-   *     ****************** WORK IN PROGRESS *******************
-   */
-
-  /* These are `classes' of fonts that can be grouped together and used in */
-  /* 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] =
-  {
-    { "MS Legacy Fonts",
-      { "Aharoni",
-        "Andale Mono",
-        "Andalus",
-        "Angsana New",
-        "AngsanaUPC",
-        "Arabic Transparent",
-        "Arial Black",
-        "Arial Narrow",
-        "Arial Unicode MS",
-        "Arial",
-        "Batang",
-        "Browallia New",
-        "BrowalliaUPC",
-        "Comic Sans MS",
-        "Cordia New",
-        "CordiaUPC",
-        "Courier New",
-        "DFKai-SB",
-        "David Transparent",
-        "David",
-        "DilleniaUPC",
-        "Estrangelo Edessa",
-        "EucrosiaUPC",
-        "FangSong_GB2312",
-        "Fixed Miriam Transparent",
-        "FrankRuehl",
-        "Franklin Gothic Medium",
-        "FreesiaUPC",
-        "Garamond",
-        "Gautami",
-        "Georgia",
-        "Gulim",
-        "Impact",
-        "IrisUPC",
-        "JasmineUPC",
-        "KaiTi_GB2312",
-        "KodchiangUPC",
-        "Latha",
-        "Levenim MT",
-        "LilyUPC",
-        "Lucida Console",
-        "Lucida Sans Unicode",
-        "MS Gothic",
-        "MS Mincho",
-        "MV Boli",
-        "Mangal",
-        "Marlett",
-        "Microsoft Sans Serif",
-        "Mingliu",
-        "Miriam Fixed",
-        "Miriam Transparent",
-        "Miriam",
-        "Narkisim",
-        "Palatino Linotype",
-        "Raavi",
-        "Rod Transparent",
-        "Rod",
-        "Shruti",
-        "SimHei",
-        "Simplified Arabic Fixed",
-        "Simplified Arabic",
-        "Simsun",
-        "Sylfaen",
-        "Symbol",
-        "Tahoma",
-        "Times New Roman",
-        "Traditional Arabic",
-        "Trebuchet MS",
-        "Tunga",
-        "Verdana",
-        "Webdings",
-        "Wingdings",
-        "",
-      },
-    },
-    { "Core MS Legacy Fonts",
-      { "Arial Black",
-        "Arial Narrow",
-        "Arial Unicode MS",
-        "Arial",
-        "Comic Sans MS",
-        "Courier New",
-        "Garamond",
-        "Georgia",
-        "Impact",
-        "Lucida Console",
-        "Lucida Sans Unicode",
-        "Microsoft Sans Serif",
-        "Palatino Linotype",
-        "Tahoma",
-        "Times New Roman",
-        "Trebuchet MS",
-        "Verdana",
-        "",
-      },
-    },
-    { "Apple Legacy Fonts",
-      { "Geneva",
-        "Times",
-        "Monaco",
-        "Century",
-        "Chalkboard",
-        "Lobster",
-        "Century Gothic",
-        "Optima",
-        "Lucida Grande",
-        "Gill Sans",
-        "Baskerville",
-        "Helvetica",
-        "Helvetica Neue",
-        "",
-      },
-    },
-    { "Legacy Sans Fonts",
-      { "Andale Mono",
-        "Arial Unicode MS",
-        "Arial",
-        "Century Gothic",
-        "Comic Sans MS",
-        "Franklin Gothic Medium",
-        "Geneva",
-        "Lucida Console",
-        "Lucida Grande",
-        "Lucida Sans Unicode",
-        "Lucida Sans Typewriter",
-        "Microsoft Sans Serif",
-        "Monaco",
-        "Tahoma",
-        "Trebuchet MS",
-        "Verdana",
-        "",
-      },
-    },
-
-    { "Misc Legacy Fonts",
-      { "Dark Courier", "", }, },
-    { "Verdana Clones",
-      { "DejaVu Sans",
-        "Bitstream Vera Sans", "", }, },
-    { "Verdana and Clones",
-      { "DejaVu Sans",
-        "Bitstream Vera Sans",
-        "Verdana", "", }, },
-  };
-
-
-  /* Define this to force natural (i.e. not bitmap-compatible) widths.     */
-  /* The default leans strongly towards natural widths except for a few    */
-  /* legacy fonts where a selective combination produces nicer results.    */
-/* #define FORCE_NATURAL_WIDTHS   */
-
-
-  /* Define `classes' of styles that can be grouped together and used in   */
-  /* rules below.  A blank entry "" is required at the end of these!       */
-#define STYLE_CLASS_RULES_SIZE  5
-
-  static const SPH_Font_Class  STYLE_CLASS_Rules
-                               [STYLE_CLASS_RULES_SIZE] =
-  {
-    { "Regular Class",
-      { "Regular",
-        "Book",
-        "Medium",
-        "Roman",
-        "Normal",
-        "",
-      },
-    },
-    { "Regular/Italic Class",
-      { "Regular",
-        "Book",
-        "Medium",
-        "Italic",
-        "Oblique",
-        "Roman",
-        "Normal",
-        "",
-      },
-    },
-    { "Bold/BoldItalic Class",
-      { "Bold",
-        "Bold Italic",
-        "Black",
-        "",
-      },
-    },
-    { "Bold/Italic/BoldItalic Class",
-      { "Bold",
-        "Bold Italic",
-        "Black",
-        "Italic",
-        "Oblique",
-        "",
-      },
-    },
-    { "Regular/Bold Class",
-      { "Regular",
-        "Book",
-        "Medium",
-        "Normal",
-        "Roman",
-        "Bold",
-        "Black",
-        "",
-      },
-    },
-  };
-
-
-  /* Force special legacy fixes for fonts.                                 */
-#define COMPATIBILITY_MODE_RULES_SIZE  1
-
-  static const SPH_TweakRule  COMPATIBILITY_MODE_Rules
-                              [COMPATIBILITY_MODE_RULES_SIZE] =
-  {
-    { "Verdana Clones", 0, "", 0 },
-  };
-
-
-  /* Don't do subpixel (ignore_x_mode) hinting; do normal hinting.         */
-#define PIXEL_HINTING_RULES_SIZE  2
-
-  static const SPH_TweakRule  PIXEL_HINTING_Rules
-                              [PIXEL_HINTING_RULES_SIZE] =
-  {
-    /* these characters are almost always safe */
-    { "Courier New", 12, "Italic", 'z' },
-    { "Courier New", 11, "Italic", 'z' },
-  };
-
-
-  /* Subpixel hinting ignores SHPIX rules on X.  Force SHPIX for these.    */
-#define DO_SHPIX_RULES_SIZE  1
-
-  static const SPH_TweakRule  DO_SHPIX_Rules
-                              [DO_SHPIX_RULES_SIZE] =
-  {
-    { "-", 0, "", 0 },
-  };
-
-
-  /* Skip Y moves that start with a point that is not on a Y pixel         */
-  /* boundary and don't move that point to a Y pixel boundary.             */
-#define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE  4
-
-  static const SPH_TweakRule  SKIP_NONPIXEL_Y_MOVES_Rules
-                              [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] =
-  {
-    /* fix vwxyz thinness */
-    { "Consolas", 0, "", 0 },
-    /* Fix thin middle stems */
-    { "Core MS Legacy Fonts", 0, "Regular", 0 },
-    /* Cyrillic small letter I */
-    { "Legacy Sans Fonts", 0, "", 0 },
-    /* Fix artifacts with some Regular & Bold */
-    { "Verdana Clones", 0, "", 0 },
-  };
-
-
-#define SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE  1
-
-  static const SPH_TweakRule  SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions
-                              [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
-  {
-    /* Fixes < and > */
-    { "Courier New", 0, "Regular", 0 },
-  };
-
-
-  /* Skip Y moves that start with a point that is not on a Y pixel         */
-  /* boundary and don't move that point to a Y pixel boundary.             */
-#define SKIP_NONPIXEL_Y_MOVES_DELTAP_RULES_SIZE  2
-
-  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' },
-    { "Georgia", 0, "Regular/Bold Class", 'N' },
-  };
-
-
-  /* Skip Y moves that move a point off a Y pixel boundary.                */
-#define SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE  1
-
-  static const SPH_TweakRule  SKIP_OFFPIXEL_Y_MOVES_Rules
-                              [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] =
-  {
-    { "-", 0, "", 0 },
-  };
-
-
-#define SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE  1
-
-  static const SPH_TweakRule  SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions
-                              [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
-  {
-    { "-", 0, "", 0 },
-  };
-
-
-  /* Round moves that don't move a point to a Y pixel boundary.            */
-#define ROUND_NONPIXEL_Y_MOVES_RULES_SIZE  2
-
-  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 },
-    { "Droid Sans Mono", 0, "", 0 },
-  };
-
-
-#define ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE  1
-
-  static const SPH_TweakRule  ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions
-                              [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
-  {
-    { "-", 0, "", 0 },
-  };
-
-
-  /* Allow a Direct_Move along X freedom vector if matched.                */
-#define ALLOW_X_DMOVE_RULES_SIZE  1
-
-  static const SPH_TweakRule  ALLOW_X_DMOVE_Rules
-                              [ALLOW_X_DMOVE_RULES_SIZE] =
-  {
-    /* Fixes vanishing diagonal in 4 */
-    { "Verdana", 0, "Regular", '4' },
-  };
-
-
-  /* Return MS rasterizer version 35 if matched.                           */
-#define RASTERIZER_35_RULES_SIZE  8
-
-  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' },
-    { "Times New Roman", 0, "Regular", 'j' },
-    { "Times New Roman", 0, "Regular", 'm' },
-    { "Times New Roman", 0, "Regular", 'r' },
-    { "Times New Roman", 0, "Regular", 'a' },
-    { "Times New Roman", 0, "Regular", 'n' },
-    { "Times New Roman", 0, "Regular", 'p' },
-    { "Times", 0, "", 0 },
-  };
-
-
-  /* Don't round to the subpixel grid.  Round to pixel grid.               */
-#define NORMAL_ROUND_RULES_SIZE  1
-
-  static const SPH_TweakRule  NORMAL_ROUND_Rules
-                              [NORMAL_ROUND_RULES_SIZE] =
-  {
-    /* Fix serif thickness for certain ppems */
-    /* Can probably be generalized somehow   */
-    { "Courier New", 0, "", 0 },
-  };
-
-
-  /* Skip IUP instructions if matched.                                     */
-#define SKIP_IUP_RULES_SIZE  1
-
-  static const SPH_TweakRule  SKIP_IUP_Rules
-                              [SKIP_IUP_RULES_SIZE] =
-  {
-    { "Arial", 13, "Regular", 'a' },
-  };
-
-
-  /* Skip MIAP Twilight hack if matched.                                   */
-#define MIAP_HACK_RULES_SIZE  1
-
-  static const SPH_TweakRule  MIAP_HACK_Rules
-                              [MIAP_HACK_RULES_SIZE] =
-  {
-    { "Geneva", 12, "", 0 },
-  };
-
-
-  /* Skip DELTAP instructions if matched.                                  */
-#define ALWAYS_SKIP_DELTAP_RULES_SIZE  23
-
-  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 */
-    { "Trebuchet MS", 14, "Regular", 'e' },
-    { "Trebuchet MS", 13, "Regular", 'e' },
-    { "Trebuchet MS", 15, "Regular", 'e' },
-    { "Trebuchet MS", 0, "Italic", 'v' },
-    { "Trebuchet MS", 0, "Italic", 'w' },
-    { "Trebuchet MS", 0, "Regular", 'Y' },
-    { "Arial", 11, "Regular", 's' },
-    /* prevent problems with '3' and others */
-    { "Verdana", 10, "Regular", 0 },
-    { "Verdana", 9, "Regular", 0 },
-    /* Cyrillic small letter short I */
-    { "Legacy Sans Fonts", 0, "", 0x438 },
-    { "Legacy Sans Fonts", 0, "", 0x439 },
-    { "Arial", 10, "Regular", '6' },
-    { "Arial", 0, "Bold/BoldItalic Class", 'a' },
-    /* Make horizontal stems consistent with the rest */
-    { "Arial", 24, "Bold", 'a' },
-    { "Arial", 25, "Bold", 'a' },
-    { "Arial", 24, "Bold", 's' },
-    { "Arial", 25, "Bold", 's' },
-    { "Arial", 34, "Bold", 's' },
-    { "Arial", 35, "Bold", 's' },
-    { "Arial", 36, "Bold", 's' },
-    { "Arial", 25, "Regular", 's' },
-    { "Arial", 26, "Regular", 's' },
-  };
-
-
-  /* Always do DELTAP instructions if matched.                             */
-#define ALWAYS_DO_DELTAP_RULES_SIZE  1
-
-  static const SPH_TweakRule  ALWAYS_DO_DELTAP_Rules
-                              [ALWAYS_DO_DELTAP_RULES_SIZE] =
-  {
-    { "-", 0, "", 0 },
-  };
-
-
-  /* Don't allow ALIGNRP after IUP.                                        */
-#define NO_ALIGNRP_AFTER_IUP_RULES_SIZE  1
-
-  static const SPH_TweakRule  NO_ALIGNRP_AFTER_IUP_Rules
-                              [NO_ALIGNRP_AFTER_IUP_RULES_SIZE] =
-  {
-    /* Prevent creation of dents in outline */
-    { "-", 0, "", 0 },
-  };
-
-
-  /* Don't allow DELTAP after IUP.                                         */
-#define NO_DELTAP_AFTER_IUP_RULES_SIZE  1
-
-  static const SPH_TweakRule  NO_DELTAP_AFTER_IUP_Rules
-                              [NO_DELTAP_AFTER_IUP_RULES_SIZE] =
-  {
-    { "-", 0, "", 0 },
-  };
-
-
-  /* Don't allow CALL after IUP.                                           */
-#define NO_CALL_AFTER_IUP_RULES_SIZE  1
-
-  static const SPH_TweakRule  NO_CALL_AFTER_IUP_Rules
-                              [NO_CALL_AFTER_IUP_RULES_SIZE] =
-  {
-    /* Prevent creation of dents in outline */
-    { "-", 0, "", 0 },
-  };
-
-
-  /* De-embolden these glyphs slightly.                                    */
-#define DEEMBOLDEN_RULES_SIZE  9
-
-  static const SPH_TweakRule  DEEMBOLDEN_Rules
-                              [DEEMBOLDEN_RULES_SIZE] =
-  {
-    { "Courier New", 0, "Bold", 'A' },
-    { "Courier New", 0, "Bold", 'W' },
-    { "Courier New", 0, "Bold", 'w' },
-    { "Courier New", 0, "Bold", 'M' },
-    { "Courier New", 0, "Bold", 'X' },
-    { "Courier New", 0, "Bold", 'K' },
-    { "Courier New", 0, "Bold", 'x' },
-    { "Courier New", 0, "Bold", 'z' },
-    { "Courier New", 0, "Bold", 'v' },
-  };
-
-
-  /* Embolden these glyphs slightly.                                       */
-#define EMBOLDEN_RULES_SIZE  2
-
-  static const SPH_TweakRule  EMBOLDEN_Rules
-                              [EMBOLDEN_RULES_SIZE] =
-  {
-    { "Courier New", 0, "Regular", 0 },
-    { "Courier New", 0, "Italic", 0 },
-  };
-
-
-  /* This is a CVT hack that makes thick horizontal stems on 2, 5, 7       */
-  /* similar to Windows XP.                                                */
-#define TIMES_NEW_ROMAN_HACK_RULES_SIZE  12
-
-  static const SPH_TweakRule  TIMES_NEW_ROMAN_HACK_Rules
-                              [TIMES_NEW_ROMAN_HACK_RULES_SIZE] =
-  {
-    { "Times New Roman", 16, "Italic", '2' },
-    { "Times New Roman", 16, "Italic", '5' },
-    { "Times New Roman", 16, "Italic", '7' },
-    { "Times New Roman", 16, "Regular", '2' },
-    { "Times New Roman", 16, "Regular", '5' },
-    { "Times New Roman", 16, "Regular", '7' },
-    { "Times New Roman", 17, "Italic", '2' },
-    { "Times New Roman", 17, "Italic", '5' },
-    { "Times New Roman", 17, "Italic", '7' },
-    { "Times New Roman", 17, "Regular", '2' },
-    { "Times New Roman", 17, "Regular", '5' },
-    { "Times New Roman", 17, "Regular", '7' },
-  };
-
-
-  /* This fudges distance on 2 to get rid of the vanishing stem issue.     */
-  /* A real solution to this is certainly welcome.                         */
-#define COURIER_NEW_2_HACK_RULES_SIZE  15
-
-  static const SPH_TweakRule  COURIER_NEW_2_HACK_Rules
-                              [COURIER_NEW_2_HACK_RULES_SIZE] =
-  {
-    { "Courier New", 10, "Regular", '2' },
-    { "Courier New", 11, "Regular", '2' },
-    { "Courier New", 12, "Regular", '2' },
-    { "Courier New", 13, "Regular", '2' },
-    { "Courier New", 14, "Regular", '2' },
-    { "Courier New", 15, "Regular", '2' },
-    { "Courier New", 16, "Regular", '2' },
-    { "Courier New", 17, "Regular", '2' },
-    { "Courier New", 18, "Regular", '2' },
-    { "Courier New", 19, "Regular", '2' },
-    { "Courier New", 20, "Regular", '2' },
-    { "Courier New", 21, "Regular", '2' },
-    { "Courier New", 22, "Regular", '2' },
-    { "Courier New", 23, "Regular", '2' },
-    { "Courier New", 24, "Regular", '2' },
-  };
-
-
-#ifndef FORCE_NATURAL_WIDTHS
-
-  /* Use compatible widths with these glyphs.  Compatible widths is always */
-  /* on when doing B/W TrueType instructing, but is used selectively here, */
-  /* typically on glyphs with 3 or more vertical stems.                    */
-#define COMPATIBLE_WIDTHS_RULES_SIZE  38
-
-  static const SPH_TweakRule  COMPATIBLE_WIDTHS_Rules
-                              [COMPATIBLE_WIDTHS_RULES_SIZE] =
-  {
-    { "Arial Unicode MS", 12, "Regular Class", 'm' },
-    { "Arial Unicode MS", 14, "Regular Class", 'm' },
-    /* Cyrillic small letter sha */
-    { "Arial", 10, "Regular Class", 0x448 },
-    { "Arial", 11, "Regular Class", 'm' },
-    { "Arial", 12, "Regular Class", 'm' },
-    /* Cyrillic small letter sha */
-    { "Arial", 12, "Regular Class", 0x448 },
-    { "Arial", 13, "Regular Class", 0x448 },
-    { "Arial", 14, "Regular Class", 'm' },
-    /* Cyrillic small letter sha */
-    { "Arial", 14, "Regular Class", 0x448 },
-    { "Arial", 15, "Regular Class", 0x448 },
-    { "Arial", 17, "Regular Class", 'm' },
-    { "DejaVu Sans", 15, "Regular Class", 0 },
-    { "Microsoft Sans Serif", 11, "Regular Class", 0 },
-    { "Microsoft Sans Serif", 12, "Regular Class", 0 },
-    { "Segoe UI", 11, "Regular Class", 0 },
-    { "Monaco", 0, "Regular Class", 0 },
-    { "Segoe UI", 12, "Regular Class", 'm' },
-    { "Segoe UI", 14, "Regular Class", 'm' },
-    { "Tahoma", 11, "Regular Class", 0 },
-    { "Times New Roman", 16, "Regular Class", 'c' },
-    { "Times New Roman", 16, "Regular Class", 'm' },
-    { "Times New Roman", 16, "Regular Class", 'o' },
-    { "Times New Roman", 16, "Regular Class", 'w' },
-    { "Trebuchet MS", 11, "Regular Class", 0 },
-    { "Trebuchet MS", 12, "Regular Class", 0 },
-    { "Trebuchet MS", 14, "Regular Class", 0 },
-    { "Trebuchet MS", 15, "Regular Class", 0 },
-    { "Ubuntu", 12, "Regular Class", 'm' },
-    /* Cyrillic small letter sha */
-    { "Verdana", 10, "Regular Class", 0x448 },
-    { "Verdana", 11, "Regular Class", 0x448 },
-    { "Verdana and Clones", 12, "Regular Class", 'i' },
-    { "Verdana and Clones", 12, "Regular Class", 'j' },
-    { "Verdana and Clones", 12, "Regular Class", 'l' },
-    { "Verdana and Clones", 12, "Regular Class", 'm' },
-    { "Verdana and Clones", 13, "Regular Class", 'i' },
-    { "Verdana and Clones", 13, "Regular Class", 'j' },
-    { "Verdana and Clones", 13, "Regular Class", 'l' },
-    { "Verdana and Clones", 14, "Regular Class", 'm' },
-  };
-
-
-  /* Scaling slightly in the x-direction prior to hinting results in       */
-  /* more visually pleasing glyphs in certain cases.                       */
-  /* This sometimes needs to be coordinated with compatible width rules.   */
-  /* A value of 1000 corresponds to a scaled value of 1.0.                 */
-
-#define X_SCALING_RULES_SIZE  50
-
-  static const SPH_ScaleRule  X_SCALING_Rules[X_SCALING_RULES_SIZE] =
-  {
-    { "DejaVu Sans", 12, "Regular Class", 'm', 950 },
-    { "Verdana and Clones", 12, "Regular Class", 'a', 1100 },
-    { "Verdana and Clones", 13, "Regular Class", 'a', 1050 },
-    { "Arial", 11, "Regular Class", 'm', 975 },
-    { "Arial", 12, "Regular Class", 'm', 1050 },
-    /* Cyrillic small letter el */
-    { "Arial", 13, "Regular Class", 0x43B, 950 },
-    { "Arial", 13, "Regular Class", 'o', 950 },
-    { "Arial", 13, "Regular Class", 'e', 950 },
-    { "Arial", 14, "Regular Class", 'm', 950 },
-    /* Cyrillic small letter el */
-    { "Arial", 15, "Regular Class", 0x43B, 925 },
-    { "Bitstream Vera Sans", 10, "Regular/Italic Class", 0, 1100 },
-    { "Bitstream Vera Sans", 12, "Regular/Italic Class", 0, 1050 },
-    { "Bitstream Vera Sans", 16, "Regular Class", 0, 1050 },
-    { "Bitstream Vera Sans", 9, "Regular/Italic Class", 0, 1050 },
-    { "DejaVu Sans", 12, "Regular Class", 'l', 975 },
-    { "DejaVu Sans", 12, "Regular Class", 'i', 975 },
-    { "DejaVu Sans", 12, "Regular Class", 'j', 975 },
-    { "DejaVu Sans", 13, "Regular Class", 'l', 950 },
-    { "DejaVu Sans", 13, "Regular Class", 'i', 950 },
-    { "DejaVu Sans", 13, "Regular Class", 'j', 950 },
-    { "DejaVu Sans", 10, "Regular/Italic Class", 0, 1100 },
-    { "DejaVu Sans", 12, "Regular/Italic Class", 0, 1050 },
-    { "Georgia", 10, "", 0, 1050 },
-    { "Georgia", 11, "", 0, 1100 },
-    { "Georgia", 12, "", 0, 1025 },
-    { "Georgia", 13, "", 0, 1050 },
-    { "Georgia", 16, "", 0, 1050 },
-    { "Georgia", 17, "", 0, 1030 },
-    { "Liberation Sans", 12, "Regular Class", 'm', 1100 },
-    { "Lucida Grande", 11, "Regular Class", 'm', 1100 },
-    { "Microsoft Sans Serif", 11, "Regular Class", 'm', 950 },
-    { "Microsoft Sans Serif", 12, "Regular Class", 'm', 1050 },
-    { "Segoe UI", 12, "Regular Class", 'H', 1050 },
-    { "Segoe UI", 12, "Regular Class", 'm', 1050 },
-    { "Segoe UI", 14, "Regular Class", 'm', 1050 },
-    { "Tahoma", 11, "Regular Class", 'i', 975 },
-    { "Tahoma", 11, "Regular Class", 'l', 975 },
-    { "Tahoma", 11, "Regular Class", 'j', 900 },
-    { "Tahoma", 11, "Regular Class", 'm', 918 },
-    { "Verdana", 10, "Regular/Italic Class", 0, 1100 },
-    { "Verdana", 12, "Regular Class", 'm', 975 },
-    { "Verdana", 12, "Regular/Italic Class", 0, 1050 },
-    { "Verdana", 13, "Regular/Italic Class", 'i', 950 },
-    { "Verdana", 13, "Regular/Italic Class", 'j', 950 },
-    { "Verdana", 13, "Regular/Italic Class", 'l', 950 },
-    { "Verdana", 16, "Regular Class", 0, 1050 },
-    { "Verdana", 9, "Regular/Italic Class", 0, 1050 },
-    { "Times New Roman", 16, "Regular Class", 'm', 918 },
-    { "Trebuchet MS", 11, "Regular Class", 'm', 800 },
-    { "Trebuchet MS", 12, "Regular Class", 'm', 800 },
-  };
-
-#else
-
-#define COMPATIBLE_WIDTHS_RULES_SIZE  1
-
-  static const SPH_TweakRule  COMPATIBLE_WIDTHS_Rules
-                              [COMPATIBLE_WIDTHS_RULES_SIZE] =
-  {
-    { "-", 0, "", 0 },
-  };
-
-
-#define X_SCALING_RULES_SIZE  1
-
-  static const SPH_ScaleRule  X_SCALING_Rules
-                              [X_SCALING_RULES_SIZE] =
-  {
-    { "-", 0, "", 0, 1000 },
-  };
-
-#endif /* FORCE_NATURAL_WIDTHS */
-
-
-  static FT_Bool
-  is_member_of_family_class( const FT_String*  detected_font_name,
-                             const FT_String*  rule_font_name )
-  {
-    FT_UInt  i, j;
-
-
-    /* Does font name match rule family? */
-    if ( ft_strcmp( detected_font_name, rule_font_name ) == 0 )
-      return TRUE;
-
-    /* Is font name a wildcard ""? */
-    if ( ft_strcmp( rule_font_name, "" ) == 0 )
-      return TRUE;
-
-    /* Is font name contained in a class list? */
-    for ( i = 0; i < FAMILY_CLASS_RULES_SIZE; i++ )
-    {
-      if ( ft_strcmp( FAMILY_CLASS_Rules[i].name, rule_font_name ) == 0 )
-      {
-        for ( j = 0; j < SPH_MAX_CLASS_MEMBERS; j++ )
-        {
-          if ( ft_strcmp( FAMILY_CLASS_Rules[i].member[j], "" ) == 0 )
-            continue;
-          if ( ft_strcmp( FAMILY_CLASS_Rules[i].member[j],
-                          detected_font_name ) == 0 )
-            return TRUE;
-        }
-      }
-    }
-
-    return FALSE;
-  }
-
-
-  static FT_Bool
-  is_member_of_style_class( const FT_String*  detected_font_style,
-                            const FT_String*  rule_font_style )
-  {
-    FT_UInt  i, j;
-
-
-    /* Does font style match rule style? */
-    if ( ft_strcmp( detected_font_style, rule_font_style ) == 0 )
-      return TRUE;
-
-    /* Is font style a wildcard ""? */
-    if ( ft_strcmp( rule_font_style, "" ) == 0 )
-      return TRUE;
-
-    /* Is font style contained in a class list? */
-    for ( i = 0; i < STYLE_CLASS_RULES_SIZE; i++ )
-    {
-      if ( ft_strcmp( STYLE_CLASS_Rules[i].name, rule_font_style ) == 0 )
-      {
-        for ( j = 0; j < SPH_MAX_CLASS_MEMBERS; j++ )
-        {
-          if ( ft_strcmp( STYLE_CLASS_Rules[i].member[j], "" ) == 0 )
-            continue;
-          if ( ft_strcmp( STYLE_CLASS_Rules[i].member[j],
-                          detected_font_style ) == 0 )
-            return TRUE;
-        }
-      }
-    }
-
-    return FALSE;
-  }
-
-
-  FT_LOCAL_DEF( FT_Bool )
-  sph_test_tweak( TT_Face               face,
-                  const FT_String*      family,
-                  FT_UInt               ppem,
-                  const FT_String*      style,
-                  FT_UInt               glyph_index,
-                  const SPH_TweakRule*  rule,
-                  FT_UInt               num_rules )
-  {
-    FT_UInt  i;
-
-
-    /* rule checks may be able to be optimized further */
-    for ( i = 0; i < num_rules; i++ )
-    {
-      if ( family                                                   &&
-           ( is_member_of_family_class ( family, rule[i].family ) ) )
-        if ( rule[i].ppem == 0    ||
-             rule[i].ppem == ppem )
-          if ( style                                             &&
-               is_member_of_style_class ( style, rule[i].style ) )
-            if ( rule[i].glyph == 0                                ||
-                 FT_Get_Char_Index( (FT_Face)face,
-                                    rule[i].glyph ) == glyph_index )
-        return TRUE;
-    }
-
-    return FALSE;
-  }
-
-
-  static FT_UInt
-  scale_test_tweak( TT_Face               face,
-                    const FT_String*      family,
-                    FT_UInt               ppem,
-                    const FT_String*      style,
-                    FT_UInt               glyph_index,
-                    const SPH_ScaleRule*  rule,
-                    FT_UInt               num_rules )
-  {
-    FT_UInt  i;
-
-
-    /* rule checks may be able to be optimized further */
-    for ( i = 0; i < num_rules; i++ )
-    {
-      if ( family                                                   &&
-           ( is_member_of_family_class ( family, rule[i].family ) ) )
-        if ( rule[i].ppem == 0    ||
-             rule[i].ppem == ppem )
-          if ( style                                            &&
-               is_member_of_style_class( style, rule[i].style ) )
-            if ( rule[i].glyph == 0                                ||
-                 FT_Get_Char_Index( (FT_Face)face,
-                                    rule[i].glyph ) == glyph_index )
-        return rule[i].scale;
-    }
-
-    return 1000;
-  }
-
-
-  FT_LOCAL_DEF( FT_UInt )
-  sph_test_tweak_x_scaling( TT_Face           face,
-                            const FT_String*  family,
-                            FT_UInt           ppem,
-                            const FT_String*  style,
-                            FT_UInt           glyph_index )
-  {
-    return scale_test_tweak( face, family, ppem, style, glyph_index,
-                             X_SCALING_Rules, X_SCALING_RULES_SIZE );
-  }
-
-
-#define TWEAK_RULES( x )                                       \
-  if ( sph_test_tweak( face, family, ppem, style, glyph_index, \
-                       x##_Rules, x##_RULES_SIZE ) )           \
-    loader->exec->sph_tweak_flags |= SPH_TWEAK_##x
-
-#define TWEAK_RULES_EXCEPTIONS( x )                                        \
-  if ( sph_test_tweak( face, family, ppem, style, glyph_index,             \
-                       x##_Rules_Exceptions, x##_RULES_EXCEPTIONS_SIZE ) ) \
-    loader->exec->sph_tweak_flags &= ~SPH_TWEAK_##x
-
-
-  FT_LOCAL_DEF( void )
-  sph_set_tweaks( TT_Loader  loader,
-                  FT_UInt    glyph_index )
-  {
-    TT_Face     face   = loader->face;
-    FT_String*  family = face->root.family_name;
-    FT_UInt     ppem   = loader->size->metrics->x_ppem;
-    FT_String*  style  = face->root.style_name;
-
-
-    /* don't apply rules if style isn't set */
-    if ( !face->root.style_name )
-      return;
-
-#ifdef SPH_DEBUG_MORE_VERBOSE
-    printf( "%s,%d,%s,%c=%d ",
-            family, ppem, style, glyph_index, glyph_index );
-#endif
-
-    TWEAK_RULES( PIXEL_HINTING );
-
-    if ( loader->exec->sph_tweak_flags & SPH_TWEAK_PIXEL_HINTING )
-    {
-      loader->exec->ignore_x_mode = FALSE;
-      return;
-    }
-
-    TWEAK_RULES( ALLOW_X_DMOVE );
-    TWEAK_RULES( ALWAYS_DO_DELTAP );
-    TWEAK_RULES( ALWAYS_SKIP_DELTAP );
-    TWEAK_RULES( DEEMBOLDEN );
-    TWEAK_RULES( DO_SHPIX );
-    TWEAK_RULES( EMBOLDEN );
-    TWEAK_RULES( MIAP_HACK );
-    TWEAK_RULES( NORMAL_ROUND );
-    TWEAK_RULES( NO_ALIGNRP_AFTER_IUP );
-    TWEAK_RULES( NO_CALL_AFTER_IUP );
-    TWEAK_RULES( NO_DELTAP_AFTER_IUP );
-    TWEAK_RULES( RASTERIZER_35 );
-    TWEAK_RULES( SKIP_IUP );
-
-    TWEAK_RULES( SKIP_OFFPIXEL_Y_MOVES );
-    TWEAK_RULES_EXCEPTIONS( SKIP_OFFPIXEL_Y_MOVES );
-
-    TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES_DELTAP );
-
-    TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES );
-    TWEAK_RULES_EXCEPTIONS( SKIP_NONPIXEL_Y_MOVES );
-
-    TWEAK_RULES( ROUND_NONPIXEL_Y_MOVES );
-    TWEAK_RULES_EXCEPTIONS( ROUND_NONPIXEL_Y_MOVES );
-
-    if ( loader->exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 )
-    {
-      if ( loader->exec->rasterizer_version != TT_INTERPRETER_VERSION_35 )
-      {
-        loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
-        loader->exec->size->cvt_ready    = -1;
-
-        tt_size_ready_bytecode(
-          loader->exec->size,
-          FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) );
-      }
-      else
-        loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
-    }
-    else
-    {
-      if ( loader->exec->rasterizer_version  !=
-           SPH_OPTION_SET_RASTERIZER_VERSION )
-      {
-        loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
-        loader->exec->size->cvt_ready    = -1;
-
-        tt_size_ready_bytecode(
-          loader->exec->size,
-          FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) );
-      }
-      else
-        loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
-    }
-
-    if ( IS_HINTED( loader->load_flags ) )
-    {
-      TWEAK_RULES( TIMES_NEW_ROMAN_HACK );
-      TWEAK_RULES( COURIER_NEW_2_HACK );
-    }
-
-    if ( sph_test_tweak( face, family, ppem, style, glyph_index,
-           COMPATIBILITY_MODE_Rules, COMPATIBILITY_MODE_RULES_SIZE ) )
-      loader->exec->face->sph_compatibility_mode = TRUE;
-
-
-    if ( IS_HINTED( loader->load_flags ) )
-    {
-      if ( sph_test_tweak( face, family, ppem, style, glyph_index,
-             COMPATIBLE_WIDTHS_Rules, COMPATIBLE_WIDTHS_RULES_SIZE ) )
-        loader->exec->compatible_widths |= TRUE;
-    }
-  }
-
-#else /* !(TT_USE_BYTECODE_INTERPRETER &&          */
-      /*   TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY) */
-
-  /* ANSI C doesn't like empty source files */
-  typedef int  _tt_subpix_dummy;
-
-#endif /* !(TT_USE_BYTECODE_INTERPRETER &&          */
-       /*   TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY) */
-
-
-/* END */
diff --git a/src/truetype/ttsubpix.h b/src/truetype/ttsubpix.h
deleted file mode 100644
index 62af4c2..0000000
--- a/src/truetype/ttsubpix.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/****************************************************************************
- *
- * ttsubpix.h
- *
- *   TrueType Subpixel Hinting.
- *
- * Copyright (C) 2010-2023 by
- * David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- * This file is part of the FreeType project, and may only be used,
- * modified, and distributed under the terms of the FreeType project
- * license, LICENSE.TXT.  By continuing to use, modify, or distribute
- * this file you indicate that you have read the license and
- * understand and accept it fully.
- *
- */
-
-
-#ifndef TTSUBPIX_H_
-#define TTSUBPIX_H_
-
-#include "ttobjs.h"
-#include "ttinterp.h"
-
-
-FT_BEGIN_HEADER
-
-
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-  /**************************************************************************
-   *
-   * ID flags to identify special functions at FDEF and runtime.
-   *
-   */
-#define SPH_FDEF_INLINE_DELTA_1       0x0000001
-#define SPH_FDEF_INLINE_DELTA_2       0x0000002
-#define SPH_FDEF_DIAGONAL_STROKE      0x0000004
-#define SPH_FDEF_VACUFORM_ROUND_1     0x0000008
-#define SPH_FDEF_TTFAUTOHINT_1        0x0000010
-#define SPH_FDEF_SPACING_1            0x0000020
-#define SPH_FDEF_SPACING_2            0x0000040
-#define SPH_FDEF_TYPEMAN_STROKES      0x0000080
-#define SPH_FDEF_TYPEMAN_DIAGENDCTRL  0x0000100
-
-
-  /**************************************************************************
-   *
-   * Tweak flags that are set for each glyph by the below rules.
-   *
-   */
-#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 )
-  sph_test_tweak( TT_Face               face,
-                  const FT_String*      family,
-                  FT_UInt               ppem,
-                  const FT_String*      style,
-                  FT_UInt               glyph_index,
-                  const SPH_TweakRule*  rule,
-                  FT_UInt               num_rules );
-
-  FT_LOCAL( FT_UInt )
-  sph_test_tweak_x_scaling( TT_Face           face,
-                            const FT_String*  family,
-                            FT_UInt           ppem,
-                            const FT_String*  style,
-                            FT_UInt           glyph_index );
-
-  FT_LOCAL( void )
-  sph_set_tweaks( TT_Loader  loader,
-                  FT_UInt    glyph_index );
-
-
-  /* These macros are defined absent a method for setting them */
-#define SPH_OPTION_BITMAP_WIDTHS           FALSE
-#define SPH_OPTION_SET_SUBPIXEL            TRUE
-#define SPH_OPTION_SET_GRAYSCALE           FALSE
-#define SPH_OPTION_SET_COMPATIBLE_WIDTHS   FALSE
-#define SPH_OPTION_SET_RASTERIZER_VERSION  38
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
-
-FT_END_HEADER
-
-#endif /* TTSUBPIX_H_ */
-
-
-/* END */
diff --git a/src/type1/t1afm.c b/src/type1/t1afm.c
index 787aa92..d9b9398 100644
--- a/src/type1/t1afm.c
+++ b/src/type1/t1afm.c
@@ -299,7 +299,7 @@
       /* ascender and descender are optional and could both be zero */
       /* check if values are meaningful before overriding defaults  */
       if ( fi->Ascender > fi->Descender )
-      {  
+      {
         /* no `U' suffix here to 0x8000! */
         t1_face->ascender  = (FT_Short)( ( fi->Ascender  + 0x8000 ) >> 16 );
         t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000 ) >> 16 );
@@ -405,7 +405,7 @@
 #else /* T1_CONFIG_OPTION_NO_AFM */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _t1_afm_dummy;
+  typedef int  t1_afm_dummy_;
 
 #endif /* T1_CONFIG_OPTION_NO_AFM */
 
diff --git a/src/type1/t1driver.c b/src/type1/t1driver.c
index ded3b26..a4cdf37 100644
--- a/src/type1/t1driver.c
+++ b/src/type1/t1driver.c
@@ -56,28 +56,32 @@
    *
    */
 
-  static FT_Error
-  t1_get_glyph_name( T1_Face     face,
+  FT_CALLBACK_DEF( FT_Error )
+  t1_get_glyph_name( FT_Face     face,        /* T1_Face */
                      FT_UInt     glyph_index,
                      FT_Pointer  buffer,
                      FT_UInt     buffer_max )
   {
-    FT_STRCPYN( buffer, face->type1.glyph_names[glyph_index], buffer_max );
+    T1_Face  t1face = (T1_Face)face;
+
+
+    FT_STRCPYN( buffer, t1face->type1.glyph_names[glyph_index], buffer_max );
 
     return FT_Err_Ok;
   }
 
 
-  static FT_UInt
-  t1_get_name_index( T1_Face           face,
+  FT_CALLBACK_DEF( FT_UInt )
+  t1_get_name_index( FT_Face           face,        /* T1_Face */
                      const FT_String*  glyph_name )
   {
-    FT_Int  i;
+    T1_Face  t1face = (T1_Face)face;
+    FT_Int   i;
 
 
-    for ( i = 0; i < face->type1.num_glyphs; i++ )
+    for ( i = 0; i < t1face->type1.num_glyphs; i++ )
     {
-      FT_String*  gname = face->type1.glyph_names[i];
+      FT_String*  gname = t1face->type1.glyph_names[i];
 
 
       if ( !ft_strcmp( glyph_name, gname ) )
@@ -90,8 +94,8 @@
 
   static const FT_Service_GlyphDictRec  t1_service_glyph_dict =
   {
-    (FT_GlyphDict_GetNameFunc)  t1_get_glyph_name,    /* get_name   */
-    (FT_GlyphDict_NameIndexFunc)t1_get_name_index     /* name_index */
+    t1_get_glyph_name,  /* FT_GlyphDict_GetNameFunc   get_name   */
+    t1_get_name_index   /* FT_GlyphDict_NameIndexFunc name_index */
   };
 
 
@@ -101,9 +105,12 @@
    */
 
   static const char*
-  t1_get_ps_name( T1_Face  face )
+  t1_get_ps_name( FT_Face  face )    /* T1_Face */
   {
-    return (const char*) face->type1.font_name;
+    T1_Face  t1face = (T1_Face)face;
+
+
+    return (const char*) t1face->type1.font_name;
   }
 
 
@@ -121,30 +128,28 @@
 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
   static const FT_Service_MultiMastersRec  t1_service_multi_masters =
   {
-    (FT_Get_MM_Func)        T1_Get_Multi_Master,    /* get_mm                    */
-    (FT_Set_MM_Design_Func) T1_Set_MM_Design,       /* set_mm_design             */
-    (FT_Set_MM_Blend_Func)  T1_Set_MM_Blend,        /* set_mm_blend              */
-    (FT_Get_MM_Blend_Func)  T1_Get_MM_Blend,        /* get_mm_blend              */
-    (FT_Get_MM_Var_Func)    T1_Get_MM_Var,          /* get_mm_var                */
-    (FT_Set_Var_Design_Func)T1_Set_Var_Design,      /* set_var_design            */
-    (FT_Get_Var_Design_Func)T1_Get_Var_Design,      /* get_var_design            */
-    (FT_Set_Instance_Func)  T1_Reset_MM_Blend,      /* set_instance              */
-    (FT_Set_MM_WeightVector_Func)
-                            T1_Set_MM_WeightVector, /* set_mm_weightvector       */
-    (FT_Get_MM_WeightVector_Func)
-                            T1_Get_MM_WeightVector, /* get_mm_weightvector       */
-    (FT_Var_Load_Delta_Set_Idx_Map_Func)
-                            NULL,                   /* load_delta_set_idx_map    */
-    (FT_Var_Load_Item_Var_Store_Func)
-                            NULL,                   /* load_item_variation_store */
-    (FT_Var_Get_Item_Delta_Func)
-                            NULL,                   /* get_item_delta            */
-    (FT_Var_Done_Item_Var_Store_Func)
-                            NULL,                   /* done_item_variation_store */
-    (FT_Var_Done_Delta_Set_Idx_Map_Func)
-                            NULL,                   /* done_delta_set_index_map  */
-    (FT_Get_Var_Blend_Func) NULL,                   /* get_var_blend             */
-    (FT_Done_Blend_Func)    T1_Done_Blend           /* done_blend                */
+    T1_Get_Multi_Master,    /* FT_Get_MM_Func             get_mm             */
+    T1_Set_MM_Design,       /* FT_Set_MM_Design_Func      set_mm_design      */
+    T1_Set_MM_Blend,        /* FT_Set_MM_Blend_Func       set_mm_blend       */
+    T1_Get_MM_Blend,        /* FT_Get_MM_Blend_Func       get_mm_blend       */
+    T1_Get_MM_Var,          /* FT_Get_MM_Var_Func         get_mm_var         */
+    T1_Set_Var_Design,      /* FT_Set_Var_Design_Func     set_var_design     */
+    T1_Get_Var_Design,      /* FT_Get_Var_Design_Func     get_var_design     */
+    T1_Reset_MM_Blend,      /* FT_Set_Named_Instance_Func set_named_instance */
+    NULL,   /* FT_Get_Default_Named_Instance_Func get_default_named_instance */
+    T1_Set_MM_WeightVector,
+            /* FT_Set_MM_WeightVector_Func        set_mm_weightvector        */
+    T1_Get_MM_WeightVector,
+            /* FT_Get_MM_WeightVector_Func        get_mm_weightvector        */
+
+    NULL,   /* FT_Construct_PS_Name_Func          construct_ps_name          */
+    NULL,   /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map     */
+    NULL,   /* FT_Var_Load_Item_Var_Store_Func    load_item_variation_store  */
+    NULL,   /* FT_Var_Get_Item_Delta_Func         get_item_delta             */
+    NULL,   /* FT_Var_Done_Item_Var_Store_Func    done_item_variation_store  */
+    NULL,   /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map   */
+    NULL,           /* FT_Get_Var_Blend_Func      get_var_blend              */
+    T1_Done_Blend   /* FT_Done_Blend_Func         done_blend                 */
   };
 #endif
 
@@ -632,11 +637,11 @@
 
   static const FT_Service_PsInfoRec  t1_service_ps_info =
   {
-    (PS_GetFontInfoFunc)   t1_ps_get_font_info,    /* ps_get_font_info    */
-    (PS_GetFontExtraFunc)  t1_ps_get_font_extra,   /* ps_get_font_extra   */
-    (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names,  /* ps_has_glyph_names  */
-    (PS_GetFontPrivateFunc)t1_ps_get_font_private, /* ps_get_font_private */
-    (PS_GetFontValueFunc)  t1_ps_get_font_value,   /* ps_get_font_value   */
+    t1_ps_get_font_info,     /* PS_GetFontInfoFunc    ps_get_font_info    */
+    t1_ps_get_font_extra,    /* PS_GetFontExtraFunc   ps_get_font_extra   */
+    t1_ps_has_glyph_names,   /* PS_HasGlyphNamesFunc  ps_has_glyph_names  */
+    t1_ps_get_font_private,  /* PS_GetFontPrivateFunc ps_get_font_private */
+    t1_ps_get_font_value,    /* PS_GetFontValueFunc   ps_get_font_value   */
   };
 
 
@@ -656,9 +661,9 @@
   FT_DEFINE_SERVICE_PROPERTIESREC(
     t1_service_properties,
 
-    (FT_Properties_SetFunc)ps_property_set,      /* set_property */
-    (FT_Properties_GetFunc)ps_property_get )     /* get_property */
-
+    ps_property_set,  /* FT_Properties_SetFunc set_property */
+    ps_property_get   /* FT_Properties_GetFunc get_property */
+  )
 
   /*
    * SERVICE LIST
diff --git a/src/type1/t1load.c b/src/type1/t1load.c
index 5a1afd8..be7cd0f 100644
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -73,7 +73,8 @@
 
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
-#define IS_INCREMENTAL  FT_BOOL( face->root.internal->incremental_interface )
+#define IS_INCREMENTAL  \
+          FT_BOOL( FT_FACE( face )->internal->incremental_interface )
 #else
 #define IS_INCREMENTAL  0
 #endif
@@ -174,10 +175,11 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Get_Multi_Master( T1_Face           face,
+  T1_Get_Multi_Master( FT_Face           face,    /* T1_Face */
                        FT_Multi_Master*  master )
   {
-    PS_Blend  blend = face->blend;
+    T1_Face   t1face = (T1_Face)face;
+    PS_Blend  blend  = t1face->blend;
     FT_UInt   n;
     FT_Error  error;
 
@@ -225,11 +227,12 @@
     for ( j = 1; j < axismap->num_points; j++ )
     {
       if ( ncv <= axismap->blend_points[j] )
-        return INT_TO_FIXED( axismap->design_points[j - 1] ) +
-               ( axismap->design_points[j] - axismap->design_points[j - 1] ) *
-               FT_DivFix( ncv - axismap->blend_points[j - 1],
-                          axismap->blend_points[j] -
-                            axismap->blend_points[j - 1] );
+        return INT_TO_FIXED( axismap->design_points[j - 1] +
+                               FT_MulDiv( ncv - axismap->blend_points[j - 1],
+                                          axismap->design_points[j] -
+                                            axismap->design_points[j - 1],
+                                          axismap->blend_points[j] -
+                                            axismap->blend_points[j - 1] ) );
     }
 
     return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] );
@@ -284,16 +287,17 @@
    * arguments needed by the GX var distortable fonts.
    */
   FT_LOCAL_DEF( FT_Error )
-  T1_Get_MM_Var( T1_Face      face,
+  T1_Get_MM_Var( FT_Face      face,    /* T1_Face */
                  FT_MM_Var*  *master )
   {
-    FT_Memory        memory = face->root.memory;
-    FT_MM_Var       *mmvar = NULL;
+    T1_Face          t1face = (T1_Face)face;
+    FT_Memory        memory = FT_FACE_MEMORY( face );
+    FT_MM_Var       *mmvar  = NULL;
     FT_Multi_Master  mmaster;
     FT_Error         error;
     FT_UInt          i;
     FT_Fixed         axiscoords[T1_MAX_MM_AXIS];
-    PS_Blend         blend = face->blend;
+    PS_Blend         blend  = t1face->blend;
     FT_UShort*       axis_flags;
 
     FT_Offset  mmvar_size;
@@ -319,9 +323,9 @@
                                   sizeof ( FT_UShort ) );
     axis_size       = mmaster.num_axis * sizeof ( FT_Var_Axis );
 
-    if ( FT_ALLOC( mmvar, mmvar_size +
-                          axis_flags_size +
-                          axis_size ) )
+    if ( FT_QALLOC( mmvar, mmvar_size +
+                           axis_flags_size +
+                           axis_size ) )
       goto Exit;
 
     mmvar->num_axis        = mmaster.num_axis;
@@ -332,8 +336,7 @@
     /* to make `FT_Get_Var_Axis_Flags' work: the function expects that the */
     /* values directly follow the data of `FT_MM_Var'                      */
     axis_flags = (FT_UShort*)( (char*)mmvar + mmvar_size );
-    for ( i = 0; i < mmaster.num_axis; i++ )
-      axis_flags[i] = 0;
+    FT_ARRAY_ZERO( axis_flags, mmaster.num_axis );
 
     mmvar->axis       = (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size );
     mmvar->namedstyle = NULL;
@@ -438,32 +441,21 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Set_MM_Blend( T1_Face    face,
+  T1_Set_MM_Blend( FT_Face    face,       /* T1_Face */
                    FT_UInt    num_coords,
                    FT_Fixed*  coords )
   {
-    FT_Error  error;
-
-
-    error = t1_set_mm_blend( face, num_coords, coords );
-    if ( error )
-      return error;
-
-    if ( num_coords )
-      face->root.face_flags |= FT_FACE_FLAG_VARIATION;
-    else
-      face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
-
-    return FT_Err_Ok;
+    return t1_set_mm_blend( (T1_Face)face, num_coords, coords );
   }
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Get_MM_Blend( T1_Face    face,
+  T1_Get_MM_Blend( FT_Face    face,       /* T1_Face */
                    FT_UInt    num_coords,
                    FT_Fixed*  coords )
   {
-    PS_Blend  blend = face->blend;
+    T1_Face   t1face = (T1_Face)face;
+    PS_Blend  blend  = t1face->blend;
 
     FT_Fixed  axiscoords[4];
     FT_UInt   i, nc;
@@ -494,11 +486,12 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Set_MM_WeightVector( T1_Face    face,
+  T1_Set_MM_WeightVector( FT_Face    face,          /* T1_Face */
                           FT_UInt    len,
                           FT_Fixed*  weightvector )
   {
-    PS_Blend  blend = face->blend;
+    T1_Face   t1face = (T1_Face)face;
+    PS_Blend  blend  = t1face->blend;
     FT_UInt   i, n;
 
 
@@ -522,11 +515,6 @@
 
       for ( ; i < blend->num_designs; i++ )
         blend->weight_vector[i] = (FT_Fixed)0;
-
-      if ( len )
-        face->root.face_flags |= FT_FACE_FLAG_VARIATION;
-      else
-        face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
     }
 
     return FT_Err_Ok;
@@ -534,11 +522,12 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Get_MM_WeightVector( T1_Face    face,
+  T1_Get_MM_WeightVector( FT_Face    face,          /* T1_Face */
                           FT_UInt*   len,
                           FT_Fixed*  weightvector )
   {
-    PS_Blend  blend = face->blend;
+    T1_Face   t1face = (T1_Face)face;
+    PS_Blend  blend  = t1face->blend;
     FT_UInt   i;
 
 
@@ -563,12 +552,13 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Set_MM_Design( T1_Face   face,
+  T1_Set_MM_Design( FT_Face   face,       /* T1_Face */
                     FT_UInt   num_coords,
                     FT_Long*  coords )
   {
+    T1_Face   t1face = (T1_Face)face;
     FT_Error  error;
-    PS_Blend  blend = face->blend;
+    PS_Blend  blend  = t1face->blend;
     FT_UInt   n;
     FT_Fixed  final_blends[T1_MAX_MM_DESIGNS];
 
@@ -634,15 +624,10 @@
       final_blends[n] = the_blend;
     }
 
-    error = t1_set_mm_blend( face, blend->num_axis, final_blends );
+    error = t1_set_mm_blend( t1face, blend->num_axis, final_blends );
     if ( error )
       return error;
 
-    if ( num_coords )
-      face->root.face_flags |= FT_FACE_FLAG_VARIATION;
-    else
-      face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
-
     return FT_Err_Ok;
   }
 
@@ -650,7 +635,7 @@
   /* MM fonts don't have named instances, so only the design is reset */
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Reset_MM_Blend( T1_Face  face,
+  T1_Reset_MM_Blend( FT_Face  face,
                      FT_UInt  instance_index )
   {
     FT_UNUSED( instance_index );
@@ -665,7 +650,7 @@
    * arguments needed by the GX var distortable fonts.
    */
   FT_LOCAL_DEF( FT_Error )
-  T1_Set_Var_Design( T1_Face    face,
+  T1_Set_Var_Design( FT_Face    face,       /* T1_Face */
                      FT_UInt    num_coords,
                      FT_Fixed*  coords )
   {
@@ -684,11 +669,12 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Get_Var_Design( T1_Face    face,
+  T1_Get_Var_Design( FT_Face    face,       /* T1_Face */
                      FT_UInt    num_coords,
                      FT_Fixed*  coords )
   {
-    PS_Blend  blend = face->blend;
+    T1_Face   t1face = (T1_Face)face;
+    PS_Blend  blend  = t1face->blend;
 
     FT_Fixed  axiscoords[4];
     FT_UInt   i, nc;
@@ -720,10 +706,11 @@
 
 
   FT_LOCAL_DEF( void )
-  T1_Done_Blend( T1_Face  face )
+  T1_Done_Blend( FT_Face  face )    /* T1_Face */
   {
-    FT_Memory  memory = face->root.memory;
-    PS_Blend   blend  = face->blend;
+    T1_Face    t1face = (T1_Face)face;
+    FT_Memory  memory = FT_FACE_MEMORY( face );
+    PS_Blend   blend  = t1face->blend;
 
 
     if ( blend )
@@ -768,20 +755,22 @@
         dmap->num_points = 0;
       }
 
-      FT_FREE( face->blend );
+      FT_FREE( t1face->blend );
     }
   }
 
 
   static void
-  parse_blend_axis_types( T1_Face    face,
-                          T1_Loader  loader )
+  parse_blend_axis_types( FT_Face  face,     /* T1_Face */
+                          void*    loader_ )
   {
+    T1_Face      t1face = (T1_Face)face;
+    T1_Loader    loader = (T1_Loader)loader_;
     T1_TokenRec  axis_tokens[T1_MAX_MM_AXIS];
     FT_Int       n, num_axis;
-    FT_Error     error = FT_Err_Ok;
+    FT_Error     error  = FT_Err_Ok;
     PS_Blend     blend;
-    FT_Memory    memory;
+    FT_Memory    memory = FT_FACE_MEMORY( face );
 
 
     /* take an array of objects */
@@ -801,14 +790,13 @@
     }
 
     /* allocate blend if necessary */
-    error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
+    error = t1_allocate_blend( t1face, 0, (FT_UInt)num_axis );
     if ( error )
       goto Exit;
 
     FT_TRACE4(( " [" ));
 
-    blend  = face->blend;
-    memory = face->root.memory;
+    blend = t1face->blend;
 
     /* each token is an immediate containing the name of the axis */
     for ( n = 0; n < num_axis; n++ )
@@ -856,14 +844,16 @@
 
 
   static void
-  parse_blend_design_positions( T1_Face    face,
-                                T1_Loader  loader )
+  parse_blend_design_positions( FT_Face  face,     /* T1_Face */
+                                void*    loader_ )
   {
+    T1_Face      t1face   = (T1_Face)face;
+    T1_Loader    loader   = (T1_Loader)loader_;
     T1_TokenRec  design_tokens[T1_MAX_MM_DESIGNS];
     FT_Int       num_designs;
     FT_Int       num_axis = 0; /* make compiler happy */
     T1_Parser    parser   = &loader->parser;
-    FT_Memory    memory   = face->root.memory;
+    FT_Memory    memory   = FT_FACE_MEMORY( face );
     FT_Error     error    = FT_Err_Ok;
     FT_Fixed*    design_pos[T1_MAX_MM_DESIGNS];
 
@@ -921,7 +911,7 @@
           }
 
           num_axis = n_axis;
-          error = t1_allocate_blend( face,
+          error = t1_allocate_blend( t1face,
                                      (FT_UInt)num_designs,
                                      (FT_UInt)num_axis );
           if ( error )
@@ -962,7 +952,7 @@
       loader->parser.root.limit  = old_limit;
 
       /* a valid BlendDesignPosition has been parsed */
-      blend = face->blend;
+      blend = t1face->blend;
       if ( blend->design_pos[0] )
         FT_FREE( blend->design_pos[0] );
 
@@ -980,9 +970,11 @@
 
 
   static void
-  parse_blend_design_map( T1_Face    face,
-                          T1_Loader  loader )
+  parse_blend_design_map( FT_Face  face,     /* T1_Face */
+                          void*    loader_ )
   {
+    T1_Face      t1face = (T1_Face)face;
+    T1_Loader    loader = (T1_Loader)loader_;
     FT_Error     error  = FT_Err_Ok;
     T1_Parser    parser = &loader->parser;
     PS_Blend     blend;
@@ -990,7 +982,7 @@
     FT_Int       n, num_axis;
     FT_Byte*     old_cursor;
     FT_Byte*     old_limit;
-    FT_Memory    memory = face->root.memory;
+    FT_Memory    memory = FT_FACE_MEMORY( face );
 
 
     T1_ToTokenArray( parser, axis_tokens,
@@ -1011,10 +1003,10 @@
     old_cursor = parser->root.cursor;
     old_limit  = parser->root.limit;
 
-    error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
+    error = t1_allocate_blend( t1face, 0, (FT_UInt)num_axis );
     if ( error )
       goto Exit;
-    blend = face->blend;
+    blend = t1face->blend;
 
     FT_TRACE4(( " [" ));
 
@@ -1089,15 +1081,17 @@
 
 
   static void
-  parse_weight_vector( T1_Face    face,
-                       T1_Loader  loader )
+  parse_weight_vector( FT_Face  face,     /* T1_Face */
+                       void*    loader_ )
   {
+    T1_Face      t1face = (T1_Face)face;
+    T1_Loader    loader = (T1_Loader)loader_;
     T1_TokenRec  design_tokens[T1_MAX_MM_DESIGNS];
     FT_Int       num_designs;
     FT_Error     error  = FT_Err_Ok;
-    FT_Memory    memory = face->root.memory;
+    FT_Memory    memory = FT_FACE_MEMORY( face );
     T1_Parser    parser = &loader->parser;
-    PS_Blend     blend  = face->blend;
+    PS_Blend     blend  = t1face->blend;
     T1_Token     token;
     FT_Int       n;
     FT_Byte*     old_cursor;
@@ -1122,10 +1116,10 @@
 
     if ( !blend || !blend->num_designs )
     {
-      error = t1_allocate_blend( face, (FT_UInt)num_designs, 0 );
+      error = t1_allocate_blend( t1face, (FT_UInt)num_designs, 0 );
       if ( error )
         goto Exit;
-      blend = face->blend;
+      blend = t1face->blend;
     }
     else if ( blend->num_designs != (FT_UInt)num_designs )
     {
@@ -1173,11 +1167,15 @@
   /* e.g., /BuildCharArray [0 0 0 0 0 0 0 0] def           */
   /* we're only interested in the number of array elements */
   static void
-  parse_buildchar( T1_Face    face,
-                   T1_Loader  loader )
+  parse_buildchar( FT_Face  face,     /* T1_Face */
+                   void*    loader_ )
   {
-    face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser,
-                                                    0, NULL, 0 );
+    T1_Face    t1face = (T1_Face)face;
+    T1_Loader  loader = (T1_Loader)loader_;
+
+
+    t1face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser,
+                                                      0, NULL, 0 );
 
 #ifdef FT_DEBUG_LEVEL_TRACE
     {
@@ -1185,7 +1183,7 @@
 
 
       FT_TRACE4(( " [" ));
-      for ( i = 0; i < face->len_buildchar; i++ )
+      for ( i = 0; i < t1face->len_buildchar; i++ )
         FT_TRACE4(( " 0" ));
 
       FT_TRACE4(( "]\n" ));
@@ -1335,9 +1333,10 @@
 
 
   static void
-  parse_private( T1_Face    face,
-                 T1_Loader  loader )
+  parse_private( FT_Face  face,
+                 void*    loader_ )
   {
+    T1_Loader  loader = (T1_Loader)loader_;
     FT_UNUSED( face );
 
     loader->keywords_encountered |= T1_PRIVATE;
@@ -1401,13 +1400,14 @@
   /* and `/CharStrings' dictionaries.                                */
 
   static void
-  t1_parse_font_matrix( T1_Face    face,
-                        T1_Loader  loader )
+  t1_parse_font_matrix( FT_Face  face,     /* T1_Face */
+                        void*    loader_ )
   {
+    T1_Face     t1face = (T1_Face)face;
+    T1_Loader   loader = (T1_Loader)loader_;
     T1_Parser   parser = &loader->parser;
-    FT_Matrix*  matrix = &face->type1.font_matrix;
-    FT_Vector*  offset = &face->type1.font_offset;
-    FT_Face     root   = (FT_Face)&face->root;
+    FT_Matrix*  matrix = &t1face->type1.font_matrix;
+    FT_Vector*  offset = &t1face->type1.font_offset;
     FT_Fixed    temp[6];
     FT_Fixed    temp_scale;
     FT_Int      result;
@@ -1443,7 +1443,7 @@
     if ( temp_scale != 0x10000L )
     {
       /* set units per EM based on FontMatrix values */
-      root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
+      face->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
 
       temp[0] = FT_DivFix( temp[0], temp_scale );
       temp[1] = FT_DivFix( temp[1], temp_scale );
@@ -1471,14 +1471,16 @@
 
 
   static void
-  parse_encoding( T1_Face    face,
-                  T1_Loader  loader )
+  parse_encoding( FT_Face  face,     /* T1_Face */
+                  void*    loader_ )
   {
+    T1_Face    t1face = (T1_Face)face;
+    T1_Loader  loader = (T1_Loader)loader_;
     T1_Parser  parser = &loader->parser;
     FT_Byte*   cur;
     FT_Byte*   limit  = parser->root.limit;
 
-    PSAux_Service  psaux = (PSAux_Service)face->psaux;
+    PSAux_Service  psaux = (PSAux_Service)t1face->psaux;
 
 
     T1_Skip_Spaces( parser );
@@ -1494,7 +1496,7 @@
     /* and we must load it now                               */
     if ( ft_isdigit( *cur ) || *cur == '[' )
     {
-      T1_Encoding  encode          = &face->type1.encoding;
+      T1_Encoding  encode          = &t1face->type1.encoding;
       FT_Int       count, array_size, n;
       PS_Table     char_table      = &loader->encoding_table;
       FT_Memory    memory          = parser->root.memory;
@@ -1676,7 +1678,7 @@
       FT_TRACE4(( "]\n" ));
 #endif
 
-      face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
+      t1face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
       parser->root.cursor       = cur;
     }
 
@@ -1687,21 +1689,21 @@
       if ( cur + 17 < limit                                            &&
            ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )
       {
-        face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
+        t1face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
         FT_TRACE4(( " StandardEncoding\n" ));
       }
 
       else if ( cur + 15 < limit                                          &&
                 ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )
       {
-        face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
+        t1face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
         FT_TRACE4(( " ExpertEncoding\n" ));
       }
 
       else if ( cur + 18 < limit                                             &&
                 ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 )
       {
-        face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
+        t1face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
         FT_TRACE4(( " ISOLatin1Encoding\n" ));
       }
 
@@ -1715,9 +1717,11 @@
 
 
   static void
-  parse_subrs( T1_Face    face,
-               T1_Loader  loader )
+  parse_subrs( FT_Face  face,     /* T1_Face */
+               void*    loader_ )
   {
+    T1_Face    t1face = (T1_Face)face;
+    T1_Loader  loader = (T1_Loader)loader_;
     T1_Parser  parser = &loader->parser;
     PS_Table   table  = &loader->subrs;
     FT_Memory  memory = parser->root.memory;
@@ -1725,7 +1729,7 @@
     FT_Int     num_subrs;
     FT_UInt    count;
 
-    PSAux_Service  psaux = (PSAux_Service)face->psaux;
+    PSAux_Service  psaux = (PSAux_Service)t1face->psaux;
 
 
     T1_Skip_Spaces( parser );
@@ -1769,7 +1773,7 @@
        */
 
       FT_TRACE0(( "parse_subrs: adjusting number of subroutines"
-                  " (from %d to %ld)\n",
+                  " (from %d to %zu)\n",
                   num_subrs,
                   ( parser->root.limit - parser->root.cursor ) >> 3 ));
       num_subrs = ( parser->root.limit - parser->root.cursor ) >> 3;
@@ -1857,7 +1861,7 @@
       /*                                                         */
       /* thanks to Tom Kacvinsky for pointing this out           */
       /*                                                         */
-      if ( face->type1.private_dict.lenIV >= 0 )
+      if ( t1face->type1.private_dict.lenIV >= 0 )
       {
         FT_Byte*  temp = NULL;
 
@@ -1865,7 +1869,7 @@
         /* some fonts define empty subr records -- this is not totally */
         /* compliant to the specification (which says they should at   */
         /* least contain a `return'), but we support them anyway       */
-        if ( size < (FT_ULong)face->type1.private_dict.lenIV )
+        if ( size < (FT_ULong)t1face->type1.private_dict.lenIV )
         {
           error = FT_THROW( Invalid_File_Format );
           goto Fail;
@@ -1876,9 +1880,11 @@
           goto Fail;
         FT_MEM_COPY( temp, base, size );
         psaux->t1_decrypt( temp, size, 4330 );
-        size -= (FT_ULong)face->type1.private_dict.lenIV;
-        error = T1_Add_Table( table, (FT_Int)idx,
-                              temp + face->type1.private_dict.lenIV, size );
+        size -= (FT_ULong)t1face->type1.private_dict.lenIV;
+        error = T1_Add_Table( table,
+                              (FT_Int)idx,
+                              temp + t1face->type1.private_dict.lenIV,
+                              size );
         FT_FREE( temp );
       }
       else
@@ -1910,9 +1916,11 @@
 
 
   static void
-  parse_charstrings( T1_Face    face,
-                     T1_Loader  loader )
+  parse_charstrings( FT_Face  face,     /* T1_Face */
+                     void*    loader_ )
   {
+    T1_Face        t1face       = (T1_Face)face;
+    T1_Loader      loader       = (T1_Loader)loader_;
     T1_Parser      parser       = &loader->parser;
     PS_Table       code_table   = &loader->charstrings;
     PS_Table       name_table   = &loader->glyph_names;
@@ -1920,7 +1928,7 @@
     FT_Memory      memory       = parser->root.memory;
     FT_Error       error;
 
-    PSAux_Service  psaux        = (PSAux_Service)face->psaux;
+    PSAux_Service  psaux        = (PSAux_Service)t1face->psaux;
 
     FT_Byte*       cur          = parser->root.cursor;
     FT_Byte*       limit        = parser->root.limit;
@@ -1940,7 +1948,7 @@
     if ( num_glyphs > ( limit - cur ) >> 3 )
     {
       FT_TRACE0(( "parse_charstrings: adjusting number of glyphs"
-                  " (from %d to %ld)\n",
+                  " (from %d to %zu)\n",
                   num_glyphs, ( limit - cur ) >> 3 ));
       num_glyphs = ( limit - cur ) >> 3;
     }
@@ -2069,13 +2077,13 @@
           notdef_found = 1;
         }
 
-        if ( face->type1.private_dict.lenIV >= 0 &&
+        if ( t1face->type1.private_dict.lenIV >= 0 &&
              n < num_glyphs + TABLE_EXTEND       )
         {
           FT_Byte*  temp = NULL;
 
 
-          if ( size <= (FT_ULong)face->type1.private_dict.lenIV )
+          if ( size <= (FT_ULong)t1face->type1.private_dict.lenIV )
           {
             error = FT_THROW( Invalid_File_Format );
             goto Fail;
@@ -2086,9 +2094,11 @@
             goto Fail;
           FT_MEM_COPY( temp, base, size );
           psaux->t1_decrypt( temp, size, 4330 );
-          size -= (FT_ULong)face->type1.private_dict.lenIV;
-          error = T1_Add_Table( code_table, n,
-                                temp + face->type1.private_dict.lenIV, size );
+          size -= (FT_ULong)t1face->type1.private_dict.lenIV;
+          error = T1_Add_Table( code_table,
+                                n,
+                                temp + t1face->type1.private_dict.lenIV,
+                                size );
           FT_FREE( temp );
         }
         else
@@ -2570,7 +2580,7 @@
     {
       FT_ERROR(( "T1_Open_Face:"
                  " number-of-designs != 2 ^^ number-of-axes\n" ));
-      T1_Done_Blend( face );
+      T1_Done_Blend( FT_FACE( face ) );
     }
 
     if ( face->blend                                                     &&
@@ -2590,15 +2600,15 @@
     /* font as a normal PS font                                     */
     if ( face->blend                                             &&
          ( !face->blend->num_designs || !face->blend->num_axis ) )
-      T1_Done_Blend( face );
+      T1_Done_Blend( FT_FACE( face ) );
 
     /* the font may have no valid WeightVector */
     if ( face->blend && !face->blend->weight_vector )
-      T1_Done_Blend( face );
+      T1_Done_Blend( FT_FACE( face ) );
 
     /* the font may have no valid BlendDesignPositions */
     if ( face->blend && !face->blend->design_pos[0] )
-      T1_Done_Blend( face );
+      T1_Done_Blend( FT_FACE( face ) );
 
     /* the font may have no valid BlendDesignMap */
     if ( face->blend )
@@ -2609,7 +2619,7 @@
       for ( i = 0; i < face->blend->num_axis; i++ )
         if ( !face->blend->design_map[i].num_points )
         {
-          T1_Done_Blend( face );
+          T1_Done_Blend( FT_FACE( face ) );
           break;
         }
     }
diff --git a/src/type1/t1load.h b/src/type1/t1load.h
index f8511cc..d8c9d2d 100644
--- a/src/type1/t1load.h
+++ b/src/type1/t1load.h
@@ -66,52 +66,52 @@
 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
 
   FT_LOCAL( FT_Error )
-  T1_Get_Multi_Master( T1_Face           face,
+  T1_Get_Multi_Master( FT_Face           face,
                        FT_Multi_Master*  master );
 
   FT_LOCAL( FT_Error )
-  T1_Get_MM_Var( T1_Face      face,
+  T1_Get_MM_Var( FT_Face      face,
                  FT_MM_Var*  *master );
 
   FT_LOCAL( FT_Error )
-  T1_Set_MM_Blend( T1_Face    face,
+  T1_Set_MM_Blend( FT_Face    face,
                    FT_UInt    num_coords,
                    FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
-  T1_Get_MM_Blend( T1_Face    face,
+  T1_Get_MM_Blend( FT_Face    face,
                    FT_UInt    num_coords,
                    FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
-  T1_Set_MM_Design( T1_Face   face,
+  T1_Set_MM_Design( FT_Face   face,
                     FT_UInt   num_coords,
                     FT_Long*  coords );
 
   FT_LOCAL( FT_Error )
-  T1_Reset_MM_Blend( T1_Face  face,
+  T1_Reset_MM_Blend( FT_Face  face,
                      FT_UInt  instance_index );
 
   FT_LOCAL( FT_Error )
-  T1_Get_Var_Design( T1_Face    face,
+  T1_Get_Var_Design( FT_Face    face,
                      FT_UInt    num_coords,
                      FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
-  T1_Set_Var_Design( T1_Face    face,
+  T1_Set_Var_Design( FT_Face    face,
                      FT_UInt    num_coords,
                      FT_Fixed*  coords );
 
   FT_LOCAL( void )
-  T1_Done_Blend( T1_Face  face );
+  T1_Done_Blend( FT_Face  face );
 
   FT_LOCAL( FT_Error )
-  T1_Set_MM_WeightVector( T1_Face    face,
+  T1_Set_MM_WeightVector( FT_Face    face,
                           FT_UInt    len,
                           FT_Fixed*  weightvector );
 
   FT_LOCAL( FT_Error )
-  T1_Get_MM_WeightVector( T1_Face    face,
+  T1_Get_MM_WeightVector( FT_Face    face,
                           FT_UInt*   len,
                           FT_Fixed*  weightvector );
 
diff --git a/src/type1/t1objs.c b/src/type1/t1objs.c
index 1bb2f15..69e4fd5 100644
--- a/src/type1/t1objs.c
+++ b/src/type1/t1objs.c
@@ -167,8 +167,7 @@
       FT_Module  module;
 
 
-      module = FT_Get_Module( slot->face->driver->root.library,
-                              "pshinter" );
+      module = FT_Get_Module( slot->library, "pshinter" );
       if ( module )
       {
         T1_Hints_Funcs  funcs;
@@ -227,7 +226,7 @@
       face->len_buildchar = 0;
     }
 
-    T1_Done_Blend( face );
+    T1_Done_Blend( t1face );
     face->blend = NULL;
 #endif
 
@@ -290,7 +289,8 @@
    *
    * @Input:
    *   stream ::
-   *     input stream where to load font data.
+   *     Dummy argument for compatibility with the `FT_Face_InitFunc` API.
+   *     Ignored.  The stream should be passed through `face->root.stream`.
    *
    *   face_index ::
    *     The index of the font face in the resource.
diff --git a/src/type42/t42drivr.c b/src/type42/t42drivr.c
index ce1528e..ee5fd44 100644
--- a/src/type42/t42drivr.c
+++ b/src/type42/t42drivr.c
@@ -56,33 +56,41 @@
    *
    */
 
-  static FT_Error
-  t42_get_glyph_name( T42_Face    face,
+  FT_CALLBACK_DEF( FT_Error )
+  t42_get_glyph_name( FT_Face     face,        /* T42_Face */
                       FT_UInt     glyph_index,
                       FT_Pointer  buffer,
                       FT_UInt     buffer_max )
   {
-    FT_STRCPYN( buffer, face->type1.glyph_names[glyph_index], buffer_max );
+    T42_Face  t42face = (T42_Face)face;
+
+
+    FT_STRCPYN( buffer,
+                t42face->type1.glyph_names[glyph_index],
+                buffer_max );
 
     return FT_Err_Ok;
   }
 
 
-  static FT_UInt
-  t42_get_name_index( T42_Face          face,
+  FT_CALLBACK_DEF( FT_UInt )
+  t42_get_name_index( FT_Face           face,        /* T42_Face */
                       const FT_String*  glyph_name )
   {
-    FT_Int  i;
+    T42_Face  t42face = (T42_Face)face;
+    FT_Int    i;
 
 
-    for ( i = 0; i < face->type1.num_glyphs; i++ )
+    for ( i = 0; i < t42face->type1.num_glyphs; i++ )
     {
-      FT_String*  gname = face->type1.glyph_names[i];
+      FT_String*  gname = t42face->type1.glyph_names[i];
 
 
       if ( glyph_name[0] == gname[0] && !ft_strcmp( glyph_name, gname ) )
-        return (FT_UInt)ft_strtol( (const char *)face->type1.charstrings[i],
-                                   NULL, 10 );
+        return (FT_UInt)ft_strtol(
+                          (const char *)t42face->type1.charstrings[i],
+                          NULL,
+                          10 );
     }
 
     return 0;
@@ -102,10 +110,13 @@
    *
    */
 
-  static const char*
-  t42_get_ps_font_name( T42_Face  face )
+  FT_CALLBACK_DEF( const char* )
+  t42_get_ps_font_name( FT_Face  face )    /* T42_Face */
   {
-    return (const char*)face->type1.font_name;
+    T42_Face  t42face = (T42_Face)face;
+
+
+    return (const char*)t42face->type1.font_name;
   }
 
 
@@ -121,7 +132,7 @@
    *
    */
 
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   t42_ps_get_font_info( FT_Face          face,
                         PS_FontInfoRec*  afont_info )
   {
@@ -131,7 +142,7 @@
   }
 
 
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   t42_ps_get_font_extra( FT_Face           face,
                          PS_FontExtraRec*  afont_extra )
   {
@@ -141,7 +152,7 @@
   }
 
 
-  static FT_Int
+  FT_CALLBACK_DEF( FT_Int )
   t42_ps_has_glyph_names( FT_Face  face )
   {
     FT_UNUSED( face );
diff --git a/src/type42/t42parse.c b/src/type42/t42parse.c
index 6d765c8..f96a43b 100644
--- a/src/type42/t42parse.c
+++ b/src/type42/t42parse.c
@@ -34,19 +34,19 @@
 
 
   static void
-  t42_parse_font_matrix( T42_Face    face,
-                         T42_Loader  loader );
+  t42_parse_font_matrix( FT_Face  face,
+                         void*    loader_ );
   static void
-  t42_parse_encoding( T42_Face    face,
-                      T42_Loader  loader );
+  t42_parse_encoding( FT_Face  face,
+                      void*    loader_ );
 
   static void
-  t42_parse_charstrings( T42_Face    face,
-                         T42_Loader  loader );
+  t42_parse_charstrings( FT_Face  face,
+                         void*    loader_ );
 
   static void
-  t42_parse_sfnts( T42_Face    face,
-                   T42_Loader  loader );
+  t42_parse_sfnts( FT_Face  face,
+                   void*    loader_ );
 
 
   /* as Type42 fonts have no Private dict,         */
@@ -241,12 +241,14 @@
 
 
   static void
-  t42_parse_font_matrix( T42_Face    face,
-                         T42_Loader  loader )
+  t42_parse_font_matrix( FT_Face  face,     /* T42_Face */
+                         void*    loader_ )
   {
-    T42_Parser  parser = &loader->parser;
-    FT_Matrix*  matrix = &face->type1.font_matrix;
-    FT_Vector*  offset = &face->type1.font_offset;
+    T42_Face    t42face = (T42_Face)face;
+    T42_Loader  loader  = (T42_Loader)loader_;
+    T42_Parser  parser  = &loader->parser;
+    FT_Matrix*  matrix  = &t42face->type1.font_matrix;
+    FT_Vector*  offset  = &t42face->type1.font_offset;
     FT_Fixed    temp[6];
     FT_Fixed    temp_scale;
     FT_Int      result;
@@ -299,14 +301,16 @@
 
 
   static void
-  t42_parse_encoding( T42_Face    face,
-                      T42_Loader  loader )
+  t42_parse_encoding( FT_Face  face,
+                      void*    loader_ )
   {
-    T42_Parser  parser = &loader->parser;
+    T42_Face    t42face = (T42_Face)face;
+    T42_Loader  loader  = (T42_Loader)loader_;
+    T42_Parser  parser  = &loader->parser;
     FT_Byte*    cur;
-    FT_Byte*    limit  = parser->root.limit;
+    FT_Byte*    limit   = parser->root.limit;
 
-    PSAux_Service  psaux  = (PSAux_Service)face->psaux;
+    PSAux_Service  psaux  = (PSAux_Service)t42face->psaux;
 
 
     T1_Skip_Spaces( parser );
@@ -322,7 +326,7 @@
     /* and we must load it now                               */
     if ( ft_isdigit( *cur ) || *cur == '[' )
     {
-      T1_Encoding  encode          = &face->type1.encoding;
+      T1_Encoding  encode          = &t42face->type1.encoding;
       FT_Int       count, n;
       PS_Table     char_table      = &loader->encoding_table;
       FT_Memory    memory          = parser->root.memory;
@@ -493,8 +497,8 @@
         T1_Skip_Spaces( parser );
       }
 
-      face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
-      parser->root.cursor       = cur;
+      t42face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
+      parser->root.cursor          = cur;
     }
 
     /* Otherwise, we should have either `StandardEncoding', */
@@ -503,15 +507,15 @@
     {
       if ( cur + 17 < limit                                            &&
            ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )
-        face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
+        t42face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
 
       else if ( cur + 15 < limit                                          &&
                 ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )
-        face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
+        t42face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
 
       else if ( cur + 18 < limit                                             &&
                 ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 )
-        face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
+        t42face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
 
       else
         parser->root.error = FT_ERR( Ignore );
@@ -529,9 +533,11 @@
 
 
   static void
-  t42_parse_sfnts( T42_Face    face,
-                   T42_Loader  loader )
+  t42_parse_sfnts( FT_Face  face,
+                   void*    loader_ )
   {
+    T42_Face    t42face = (T42_Face)face;
+    T42_Loader  loader  = (T42_Loader)loader_;
     T42_Parser  parser = &loader->parser;
     FT_Memory   memory = parser->root.memory;
     FT_Byte*    cur;
@@ -548,8 +554,8 @@
     T42_Load_Status  status;
 
     /** There should only be one sfnts array, but free any previous. */
-    FT_FREE( face->ttf_data );
-    face->ttf_size = 0;
+    FT_FREE( t42face->ttf_data );
+    t42face->ttf_size = 0;
 
     /* The format is                                */
     /*                                              */
@@ -580,7 +586,7 @@
     old_string_size = 0;
     ttf_count       = 0;
     ttf_reserved    = 12;
-    if ( FT_QALLOC( face->ttf_data, ttf_reserved ) )
+    if ( FT_QALLOC( t42face->ttf_data, ttf_reserved ) )
       goto Fail;
 
     FT_TRACE2(( "\n" ));
@@ -596,7 +602,7 @@
       if ( *cur == ']' )
       {
         parser->root.cursor++;
-        face->ttf_size = ttf_count;
+        t42face->ttf_size = ttf_count;
         goto Exit;
       }
 
@@ -707,7 +713,7 @@
           /* load offset table, 12 bytes */
           if ( ttf_count < 12 )
           {
-            face->ttf_data[ttf_count++] = string_buf[n];
+            t42face->ttf_data[ttf_count++] = string_buf[n];
             continue;
           }
           else
@@ -715,7 +721,7 @@
             FT_Long ttf_reserved_prev = ttf_reserved;
 
 
-            num_tables   = 16 * face->ttf_data[4] + face->ttf_data[5];
+            num_tables   = 16 * t42face->ttf_data[4] + t42face->ttf_data[5];
             status       = BEFORE_TABLE_DIR;
             ttf_reserved = 12 + 16 * num_tables;
 
@@ -729,7 +735,7 @@
               goto Fail;
             }
 
-            if ( FT_QREALLOC( face->ttf_data, ttf_reserved_prev,
+            if ( FT_QREALLOC( t42face->ttf_data, ttf_reserved_prev,
                               ttf_reserved ) )
               goto Fail;
           }
@@ -739,7 +745,7 @@
           /* the offset table is read; read the table directory */
           if ( ttf_count < ttf_reserved )
           {
-            face->ttf_data[ttf_count++] = string_buf[n];
+            t42face->ttf_data[ttf_count++] = string_buf[n];
             continue;
           }
           else
@@ -755,7 +761,7 @@
 
             for ( i = 0; i < num_tables; i++ )
             {
-              FT_Byte*  p = face->ttf_data + 12 + 16 * i + 12;
+              FT_Byte*  p = t42face->ttf_data + 12 + 16 * i + 12;
 
 
               len = FT_PEEK_ULONG( p );
@@ -781,7 +787,7 @@
             FT_TRACE2(( "  allocating %ld bytes\n", ttf_reserved ));
             FT_TRACE2(( "\n" ));
 
-            if ( FT_QREALLOC( face->ttf_data, ttf_reserved_prev,
+            if ( FT_QREALLOC( t42face->ttf_data, ttf_reserved_prev,
                               ttf_reserved ) )
               goto Fail;
           }
@@ -795,7 +801,7 @@
             error = FT_THROW( Invalid_File_Format );
             goto Fail;
           }
-          face->ttf_data[ttf_count++] = string_buf[n];
+          t42face->ttf_data[ttf_count++] = string_buf[n];
         }
       }
 
@@ -811,8 +817,8 @@
   Exit:
     if ( parser->root.error )
     {
-      FT_FREE( face->ttf_data );
-      face->ttf_size = 0;
+      FT_FREE( t42face->ttf_data );
+      t42face->ttf_size = 0;
     }
     if ( allocated )
       FT_FREE( string_buf );
@@ -820,9 +826,11 @@
 
 
   static void
-  t42_parse_charstrings( T42_Face    face,
-                         T42_Loader  loader )
+  t42_parse_charstrings( FT_Face  face,     /* T42_Face */
+                         void*    loader_ )
   {
+    T42_Face       t42face      = (T42_Face)face;
+    T42_Loader     loader       = (T42_Loader)loader_;
     T42_Parser     parser       = &loader->parser;
     PS_Table       code_table   = &loader->charstrings;
     PS_Table       name_table   = &loader->glyph_names;
@@ -830,7 +838,7 @@
     FT_Memory      memory       = parser->root.memory;
     FT_Error       error;
 
-    PSAux_Service  psaux        = (PSAux_Service)face->psaux;
+    PSAux_Service  psaux        = (PSAux_Service)t42face->psaux;
 
     FT_Byte*       cur;
     FT_Byte*       limit        = parser->root.limit;
@@ -864,7 +872,7 @@
       if ( loader->num_glyphs > ( limit - parser->root.cursor ) >> 2 )
       {
         FT_TRACE0(( "t42_parse_charstrings: adjusting number of glyphs"
-                    " (from %d to %ld)\n",
+                    " (from %d to %zu)\n",
                     loader->num_glyphs,
                     ( limit - parser->root.cursor ) >> 2 ));
         loader->num_glyphs = ( limit - parser->root.cursor ) >> 2;
diff --git a/src/winfonts/winfnt.c b/src/winfonts/winfnt.c
index fa73ae4..1160e4e 100644
--- a/src/winfonts/winfnt.c
+++ b/src/winfonts/winfnt.c
@@ -624,31 +624,34 @@
 
 
   static FT_Error
-  fnt_cmap_init( FNT_CMap    cmap,
+  fnt_cmap_init( FT_CMap     cmap,     /* FNT_CMap */
                  FT_Pointer  pointer )
   {
-    FNT_Face  face = (FNT_Face)FT_CMAP_FACE( cmap );
-    FNT_Font  font = face->font;
+    FNT_CMap  fntcmap = (FNT_CMap)cmap;
+    FNT_Face  face    = (FNT_Face)FT_CMAP_FACE( cmap );
+    FNT_Font  font    = face->font;
 
     FT_UNUSED( pointer );
 
 
-    cmap->first = (FT_UInt32)  font->header.first_char;
-    cmap->count = (FT_UInt32)( font->header.last_char - cmap->first + 1 );
+    fntcmap->first = (FT_UInt32)font->header.first_char;
+    fntcmap->count = (FT_UInt32)( font->header.last_char -
+                                  fntcmap->first + 1 );
 
     return 0;
   }
 
 
   static FT_UInt
-  fnt_cmap_char_index( FNT_CMap   cmap,
+  fnt_cmap_char_index( FT_CMap    cmap,       /* FNT_CMap */
                        FT_UInt32  char_code )
   {
-    FT_UInt  gindex = 0;
+    FNT_CMap  fntcmap = (FNT_CMap)cmap;
+    FT_UInt   gindex  = 0;
 
 
-    char_code -= cmap->first;
-    if ( char_code < cmap->count )
+    char_code -= fntcmap->first;
+    if ( char_code < fntcmap->count )
       /* we artificially increase the glyph index; */
       /* FNT_Load_Glyph reverts to the right one   */
       gindex = (FT_UInt)( char_code + 1 );
@@ -656,26 +659,27 @@
   }
 
 
-  static FT_UInt32
-  fnt_cmap_char_next( FNT_CMap    cmap,
+  static FT_UInt
+  fnt_cmap_char_next( FT_CMap     cmap,        /* FNT_CMap */
                       FT_UInt32  *pchar_code )
   {
-    FT_UInt    gindex = 0;
-    FT_UInt32  result = 0;
+    FNT_CMap   fntcmap   = (FNT_CMap)cmap;
+    FT_UInt    gindex    = 0;
+    FT_UInt32  result    = 0;
     FT_UInt32  char_code = *pchar_code + 1;
 
 
-    if ( char_code <= cmap->first )
+    if ( char_code <= fntcmap->first )
     {
-      result = cmap->first;
+      result = fntcmap->first;
       gindex = 1;
     }
     else
     {
-      char_code -= cmap->first;
-      if ( char_code < cmap->count )
+      char_code -= fntcmap->first;
+      if ( char_code < fntcmap->count )
       {
-        result = cmap->first + char_code;
+        result = fntcmap->first + char_code;
         gindex = (FT_UInt)( char_code + 1 );
       }
     }
diff --git a/subprojects/libpng.wrap b/subprojects/libpng.wrap
index 12ba5b1..eb0785d 100644
--- a/subprojects/libpng.wrap
+++ b/subprojects/libpng.wrap
@@ -1,12 +1,13 @@
 [wrap-file]
-directory = libpng-1.6.39
-source_url = https://github.com/glennrp/libpng/archive/v1.6.39.tar.gz
-source_filename = libpng-1.6.39.tar.gz
-source_hash = a00e9d2f2f664186e4202db9299397f851aea71b36a35e74910b8820e380d441
-patch_filename = libpng_1.6.39-2_patch.zip
-patch_url = https://wrapdb.mesonbuild.com/v2/libpng_1.6.39-2/get_patch
-patch_hash = 8bcf8f69f50233f3a35e3718ab3c91b0c51b4c1a08a84c87be0b1f4813adf17f
-wrapdb_version = 1.6.39-2
+directory = libpng-1.6.40
+source_url = https://github.com/glennrp/libpng/archive/v1.6.40.tar.gz
+source_filename = libpng-1.6.40.tar.gz
+source_hash = 62d25af25e636454b005c93cae51ddcd5383c40fa14aa3dae8f6576feb5692c2
+patch_filename = libpng_1.6.40-1_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/libpng_1.6.40-1/get_patch
+patch_hash = bad558070e0a82faa5c0ae553bcd12d49021fc4b628f232a8e58c3fbd281aae1
+source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/libpng_1.6.40-1/libpng-1.6.40.tar.gz
+wrapdb_version = 1.6.40-1
 
 [provide]
 libpng = libpng_dep
diff --git a/subprojects/zlib.wrap b/subprojects/zlib.wrap
index 23af071..f9f1180 100644
--- a/subprojects/zlib.wrap
+++ b/subprojects/zlib.wrap
@@ -1,12 +1,13 @@
 [wrap-file]
-directory = zlib-1.2.13
-source_url = http://zlib.net/fossils/zlib-1.2.13.tar.gz
-source_filename = zlib-1.2.13.tar.gz
-source_hash = b3a24de97a8fdbc835b9833169501030b8977031bcb54b3b3ac13740f846ab30
-patch_filename = zlib_1.2.13-2_patch.zip
-patch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.2.13-2/get_patch
-patch_hash = a7abea3ad65dc2c291ad5fbbf5355d0585a7f7b8c935d4a74335b8fe18684506
-wrapdb_version = 1.2.13-2
+directory = zlib-1.3
+source_url = http://zlib.net/fossils/zlib-1.3.tar.gz
+source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/zlib_1.3-1/zlib-1.3.tar.gz
+source_filename = zlib-1.3.tar.gz
+source_hash = ff0ba4c292013dbc27530b3a81e1f9a813cd39de01ca5e0f8bf355702efa593e
+patch_filename = zlib_1.3-1_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.3-1/get_patch
+patch_hash = ab9d6b8167bb34a7c52b60b0cd6138aa4e0c2d31f997343a5f506f3b97b32008
+wrapdb_version = 1.3-1
 
 [provide]
 zlib = zlib_dep
diff --git a/vms_make.com b/vms_make.com
index a1ccb65..2c85a01 100644
--- a/vms_make.com
+++ b/vms_make.com
@@ -34,6 +34,13 @@
 $! 0.02 20041030 Add error handling, FreeType 2.1.9
 $!
 $ on error then goto err_exit
+$!
+$! Get platform
+$ vax      = f$getsyi("ARCH_NAME").eqs. "VAX"
+$ axp      = f$getsyi("ARCH_NAME").eqs. "Alpha"
+$ ia64     = f$getsyi("ARCH_NAME").eqs. "IA64"
+$ x86_64   = f$getsyi("ARCH_NAME").eqs. "x86_64"
+$!
 $ true  = 1
 $ false = 0
 $ tmpnam = "temp_" + f$getjpi("","pid")
@@ -48,6 +55,7 @@
 $!
 $ Make    = ""
 $ ccopt   = "/name=(as_is,short)/float=ieee"
+$ if ( x86_64 ) then cxxopt = "/name=(as_is,short)"
 $ lopts   = ""
 $ dnsrl   = ""
 $ aconf_in_file = "config.hin"
@@ -71,72 +79,100 @@
 $!
 $ gosub check_opts
 $!
-$! Create option file
-$!
-$ open/write optf 'optfile'
 $!
 $! Pull in external libraries
 $!
+$ have_png = f$search("sys$library:libpng.olb") .nes. ""
+$ have_bz2 = f$search("sys$library:libbz2.olb") .nes. ""
+$ have_z = f$search("sys$library:libz.olb") .nes. ""
+$ have_harfbuzz = f$search("sys$library:libharfbuzz.olb") .nes. ""
+$!
 $ create libs.opt
 $ open/write libsf libs.opt
-$ gosub check_create_vmslib
+$ if ( have_harfbuzz ) then write libsf "sys$library:libharfbuzz.olb/lib"
+$ if ( have_png ) then write libsf "sys$library:libpng.olb/lib"
+$ if ( have_bz2 ) then write libsf "sys$library:libbz2.olb/lib"
+$ if ( have_z ) then write libsf "sys$library:libz.olb/lib"
+$ close libsf
+$ open/write libsf libs_cxx.opt
+$ if ( have_harfbuzz ) then write libsf "sys$library:libharfbuzz.olb/lib"
+$ if ( have_png ) then write libsf "sys$library:libpng_cxx.olb/lib"
+$ if ( have_bz2 ) then write libsf "sys$library:libbz2_cxx.olb/lib"
+$ if ( have_z ) then write libsf "sys$library:libz_cxx.olb/lib"
+$ close libsf
 $!
 $! Create objects
 $!
+$ libdefs = "FT2_BUILD_LIBRARY,FT_CONFIG_OPTION_OLD_INTERNALS"
+$ if ( have_bz2 ) then libdefs=libdefs+",FT_CONFIG_OPTION_USE_BZIP2=1"
+$ if ( have_png ) then libdefs=libdefs+",FT_CONFIG_OPTION_USE_PNG=1"
+$ if ( have_z ) then libdefs=libdefs+",FT_CONFIG_OPTION_SYSTEM_ZLIB=1"
+$ if ( have_harfbuzz ) then libdefs=libdefs+",FT_CONFIG_OPTION_USE_HARFBUZZ=1"
 $ if libdefs .nes. ""
 $ then
-$   ccopt = ccopt + "/define=(" + f$extract(0,f$length(libdefs)-1,libdefs) + ")"
+$   ccopt = ccopt + "/define=(" + libdefs + ")"
+$ if ( x86_64 ) then cxxopt = cxxopt + "/define=(" + libdefs + ")"
 $ endif
 $!
 $ if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) -
     then s_case = true
 $ gosub crea_mms
 $!
-$ 'Make' /macro=(comp_flags="''ccopt'")
+$ if x86_64
+$ then
+$   'Make' /macro=(comp_flags="''ccopt'",cxxcomp_flags="''cxxopt'","X86=1")
+$ else
+$   'Make' /macro=(comp_flags="''ccopt'")
+$ endif
 $ purge/nolog [...]descrip.mms
 $!
-$! Add them to options
 $!
-$FLOOP:
-$  file = f$edit(f$search("[...]*.obj"),"UPCASE")
-$  if (file .nes. "")
-$  then
-$    if f$locate("DEMOS",file) .eqs. f$length(file) then write optf file
-$    goto floop
-$  endif
+$! Alpha & Itanium get a shareable image
 $!
-$ close optf
-$!
-$!
-$! Alpha gets a shareable image
-$!
-$ If f$getsyi("HW_MODEL") .gt. 1024
+$ If .not. vax
 $ Then
 $   write sys$output "Creating freetype2shr.exe"
-$   If f$getsyi("HW_MODEL") .le. 2048
-$   Then
-$     call anal_obj_axp 'optfile' _link.opt
-$   Else
-$     copy _link.opt_ia64 _link.opt
-$     close libsf
-$     copy libs.opt_ia64 libs.opt
-$   endif
-$   open/append  optf 'optfile'
-$   if s_case then WRITE optf "case_sensitive=YES"
-$   close optf
-$   LINK_/NODEB/SHARE=[.lib]freetype2shr.exe -
-                            'optfile'/opt,libs.opt/opt,_link.opt/opt
+$   library/extract=* [.lib]freetype.olb
+$   set def [.src.tools]
+$   cc apinames.c
+$   link apinames
+$   set def [--]
+$   pur [.include.freetype]ftmac.h
+$   rename [.include.freetype]ftmac.h [.include.freetype]ftmac.h_tmp
+$   bash builds/vms/apinames_vms.bash
+$   rename [.include.freetype]ftmac.h_tmp [.include.freetype]ftmac.h
+$   open/write file  libfreetype.opt
+$   write file "!"
+$   write file "! libfreetype.opt generated by vms_make.com"
+$   write file "!"
+$   write file "IDENTIFICATION=""freetype2 2.0"""
+$   write file "GSMATCH=LEQUAL,2,0
+$   write file "freetype.obj"
+$   close file
+$   link/nodeb/share=[.lib]freetype2shr.exe/map=libfreetype.map/full -
+      libfreetype/opt,freetype_vms/opt,libs/opt
+$   delete freetype.obj;*
+$ endif
+$ if x86_64
+$ then
+$   write sys$output "Creating freetype2shr_cxx.exe"
+$   library/extract=* [.lib]freetype_cxx.olb
+$   open/write file  libfreetype_cxx.opt
+$   write file "!"
+$   write file "! libfreetype_cxx.opt generated by vms_make.com"
+$   write file "!"
+$   write file "IDENTIFICATION=""freetype2 2.0"""
+$   write file "GSMATCH=LEQUAL,2,0
+$   write file "freetype_cxx.obj"
+$   close file
+$   link/nodeb/share=[.lib]freetype2shr_cxx.exe/map=libfreetype_cxx.map/full -
+      libfreetype_cxx/opt,freetype_vms/opt,libs_cxx/opt
+$   delete freetype_cxx.obj;*
 $ endif
 $!
 $ exit
 $!
 $
-$ERR_LIB:
-$ write sys$output "Error reading config file vmslib.dat"
-$ goto err_exit
-$FT2_ERR:
-$ write sys$output "Could not locate FreeType 2 include files"
-$ goto err_exit
 $ERR_EXIT:
 $ set message/facil/ident/sever/text
 $ close/nolog optf
@@ -174,6 +210,7 @@
 # fully.
 $ EOD
 $ write out "CFLAGS = ", ccopt
+$ if x86_64 then write out "CXXFLAGS = ", cxxopt
 $ copy sys$input: out
 $ deck
 
@@ -237,6 +274,8 @@
         $(MMS)$(MMSQUALIFIERS)
         set default [-.smooth]
         $(MMS)$(MMSQUALIFIERS)
+        set default [-.svg]
+        $(MMS)$(MMSQUALIFIERS)
         set default [-.truetype]
         $(MMS)$(MMSQUALIFIERS)
         set default [-.type1]
@@ -245,6 +284,8 @@
         $(MMS)$(MMSQUALIFIERS)
         set default [-.winfonts]
         $(MMS)$(MMSQUALIFIERS)
+        set default [-.sdf]
+        $(MMS)$(MMSQUALIFIERS)
         set default [--]
 
 # EOF
@@ -271,11 +312,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=noinfo/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=noinfo/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=ftsystem.obj
 
+OBJS64=ftsystem_64.obj
+
+OBJSCXX=ftsystem_cxx.obj
+
 all : $(OBJS)
         library/create [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library/create [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 ftsystem.obj : ftsystem.c ftconfig.h
 
@@ -302,11 +375,43 @@
 # fully.
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.autofit])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map nl: exclude hb_
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64\
+	/obj=$(MMS$TARGET_NAME)_64.obj $(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=autofit.obj
 
+OBJS64=autofit_64.obj
+
+OBJSCXX=autofit_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -332,6 +437,29 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.builds.vms],[--.include],[--.src.base])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64\
+	/obj=$(MMS$TARGET_NAME)_64.obj $(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=ftbase.obj,\
      ftbbox.obj,\
@@ -348,10 +476,54 @@
      ftstroke.obj,\
      ftsynth.obj,\
      fttype1.obj,\
-     ftwinfnt.obj
+     ftwinfnt.obj,ftpatent.obj,ftgxval.obj,ftotval.obj
+
+OBJS64=ftbase_64.obj,\
+     ftbbox_64.obj,\
+     ftbdf_64.obj,\
+     ftbitmap_64.obj,\
+     ftcid_64.obj,\
+     ftdebug_64.obj,\
+     ftfstype_64.obj,\
+     ftgasp_64.obj,\
+     ftglyph_64.obj,\
+     ftinit_64.obj,\
+     ftmm_64.obj,\
+     ftpfr_64.obj,\
+     ftstroke_64.obj,\
+     ftsynth_64.obj,\
+     fttype1_64.obj,\
+     ftwinfnt_64.obj,ftpatent_64.obj,ftgxval_64.obj,ftotval_64.obj
+
+OBJSCXX=ftbase_cxx.obj,\
+     ftbbox_cxx.obj,\
+     ftbdf_cxx.obj,\
+     ftbitmap_cxx.obj,\
+     ftcid_cxx.obj,\
+     ftdebug_cxx.obj,\
+     ftfstype_cxx.obj,\
+     ftgasp_cxx.obj,\
+     ftglyph_cxx.obj,\
+     ftinit_cxx.obj,\
+     ftmm_cxx.obj,\
+     ftpfr_cxx.obj,\
+     ftstroke_cxx.obj,\
+     ftsynth_cxx.obj,\
+     fttype1_cxx.obj,\
+     ftwinfnt_cxx.obj,ftpatent_cxx.obj,ftgxval_cxx.obj,ftotval_cxx.obj
 
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
+
+ftbase.obj : ftbase.c ftadvanc.c ftcalc.c ftcolor.c ftdbgmem.c fterrors.c\
+	ftfntfmt.c ftgloadr.c fthash.c ftlcdfil.c ftmac.c ftobjs.c ftoutln.c\
+	ftpsprop.c ftrfork.c ftsnames.c ftstream.c fttrigon.c ftutil.c
+
 
 # EOF
 $ eod
@@ -377,11 +549,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.bdf])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=noinfo/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=bdf.obj
 
+OBJS64=bdf_64.obj
+
+OBJSCXX=bdf_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -407,11 +611,46 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.cache])/nowarn
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=noinfo/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=ftcache.obj
 
+OBJS64=ftcache_64.obj
+
+OBJSCXX=ftcache_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
+
+ftcache.obj : ftcache.c ftcbasic.c ftccache.c ftccmap.c ftcglyph.c ftcimage.c \
+	ftcmanag.c ftcmru.c ftcsbits.c
 
 # EOF
 $ eod
@@ -437,11 +676,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.cff])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=cff.obj
 
+OBJS64=cff_64.obj
+
+OBJSCXX=cff_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -467,11 +738,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.cid])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=type1cid.obj
 
+OBJS64=type1cid_64.obj
+
+OBJSCXX=type1cid_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -497,11 +800,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.gxvalid])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=gxvalid.obj
 
+OBJS64=gxvalid_64.obj
+
+OBJSCXX=gxvalid_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -525,17 +860,49 @@
 # indicate that you have read the license and understand and accept it
 # fully.
 $EOD
-$ if libincs .nes. "" then write out "LIBINCS = ", libincs - ",", ","
 $ write out "COMP_FLAGS = ", ccopt
+$ if x86_64 then write out "CXXFLAGS = ", cxxopt
 $ copy sys$input: out
 $ deck
 
-CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=($(LIBINCS)[--.include],[--.src.gzip])
+CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.gzip])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=ftgzip.obj
 
+OBJS64=ftgzip_64.obj
+
+OBJSCXX=ftgzip_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -561,17 +928,49 @@
 # indicate that you have read the license and understand and accept it
 # fully.
 $EOD
-$ if libincs .nes. "" then write out "LIBINCS = ", libincs - ",", ","
 $ write out "COMP_FLAGS = ", ccopt
+$ if x86_64 then write out "CXXFLAGS = ", cxxopt
 $ copy sys$input: out
 $ deck
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.bzip2])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=ftbzip2.obj
 
+OBJS64=ftbzip2_64.obj
+
+OBJSCXX=ftbzip2_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -595,17 +994,49 @@
 # indicate that you have read the license and understand and accept it
 # fully.
 $EOD
-$ if libincs .nes. "" then write out "LIBINCS = ", libincs - ",", ","
 $ write out "COMP_FLAGS = ", ccopt
+$ if x86_64 then write out "CXXFLAGS = ", cxxopt
 $ copy sys$input: out
 $ deck
 
-CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=($(LIBINCS)[--.include],[--.src.lzw])
+CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.lzw])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=ftlzw.obj
 
+OBJS64=ftlzw_64.obj
+
+OBJSCXX=ftlzw_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -631,11 +1062,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.otvalid])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=otvalid.obj
 
+OBJS64=otvalid_64.obj
+
+OBJSCXX=otvalid_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -673,11 +1136,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.pcf])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=noinfo/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=pcf.obj
 
+OBJS64=pcf_64.obj
+
+OBJSCXX=pcf_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -703,11 +1198,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.pfr])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=pfr.obj
 
+OBJS64=pfr_64.obj
+
+OBJSCXX=pfr_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -733,11 +1260,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.psaux])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=psaux.obj
 
+OBJS64=psaux_64.obj
+
+OBJSCXX=psaux_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -763,11 +1322,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.psnames])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=pshinter.obj
 
+OBJS64=pshinter_64.obj
+
+OBJSCXX=pshinter_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -793,11 +1384,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.psnames])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=psnames.obj
 
+OBJS64=psnames_64.obj
+
+OBJSCXX=psnames_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -823,11 +1446,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.raster])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=raster.obj
 
+OBJS64=raster_64.obj
+
+OBJSCXX=raster_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -853,11 +1508,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.sfnt])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=sfnt.obj
 
+OBJS64=sfnt_64.obj
+
+OBJSCXX=sfnt_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -883,11 +1570,105 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.smooth])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=noinfo/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=smooth.obj
 
+OBJS64=smooth_64.obj
+
+OBJSCXX=smooth_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
+
+# EOF
+$ eod
+$ close out
+$ write sys$output "... [.src.svg] directory"
+$ create [.src.svg]descrip.mms
+$ open/append out [.src.svg]descrip.mms
+$ copy sys$input: out
+$ deck
+#
+# FreeType 2 smooth renderer module compilation rules for VMS
+#
+
+
+# Copyright 2001-2019 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT.  By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+
+
+CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.svg])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=noinfo/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
+
+OBJS=svg.obj
+
+OBJS64=svg_64.obj
+
+OBJSCXX=svg_cxx.obj
+
+all : $(OBJS)
+        library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -913,11 +1694,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.truetype])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=truetype.obj
 
+OBJS64=truetype_64.obj
+
+OBJSCXX=truetype_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -943,11 +1756,109 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.type1])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=type1.obj
 
+OBJS64=type1_64.obj
+
+OBJSCXX=type1_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
+
+type1.obj : type1.c t1parse.c t1load.c t1objs.c t1driver.c t1gload.c t1afm.c
+
+# EOF
+$ eod
+$ close out
+$ write sys$output "... [.src.sdf] directory"
+$ create [.src.sdf]descrip.mms
+$ open/append out [.src.sdf]descrip.mms
+$ copy sys$input: out
+$ deck
+#
+# FreeType 2 sdf driver compilation rules for VMS
+#
+
+
+# Copyright 1996-2019 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT.  By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+
+
+CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.type1])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=noinfo/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
+
+OBJS=sdf.obj
+
+OBJS64=sdf_64.obj
+
+OBJSCXX=sdf_cxx.obj
+
+all : $(OBJS)
+        library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
+
+sdf.obj : sdf.c ftbsdf.c ftsdf.c ftsdfcommon.c ftsdfrend.c
 
 # EOF
 $ eod
@@ -973,11 +1884,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.type42])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=type42.obj
 
+OBJS64=type42_64.obj
+
+OBJSCXX=type42_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -1003,11 +1946,43 @@
 
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.winfonts])
+.ifdef X86
+CXXFLAGS=$(CXXCOMP_FLAGS)$(DEBUG)/list/show=all/include=([],[--.include],[--.src.base])
+.endif
+
+.ifdef X86
+.c.obj :
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_cxx.obj $(MMS$TARGET_NAME).c
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	cxx$(CXXFLAGS)/warn=noinfo/obj=$(MMS$TARGET_NAME)_64_cxx.obj $(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.else
+.c.obj :
+	cc$(CFLAGS)/warn=noinfo/point=32/list/show=all $(MMS$TARGET_NAME).c
+	pipe link/map/full/exec=nl: $(MMS$TARGET_NAME).obj | copy sys$input nl:
+	mc sys$library:vms_auto64 $(MMS$TARGET_NAME).map
+	cc$(CFLAGS)/warn=(noinfo,disable=(MAYLOSEDATA3))/point=64/obj=$(MMS$TARGET_NAME)_64.obj\
+	$(MMS$TARGET_NAME)_64.c
+	delete $(MMS$TARGET_NAME)_64.c;*
+.endif
 
 OBJS=winfnt.obj
 
+OBJS64=winfnt_64.obj
+
+OBJSCXX=winfnt_cxx.obj
+
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
+        library [--.lib]freetype.olb $(OBJS64)
+.ifdef X86
+        library [--.lib]freetype_cxx.olb $(OBJSCXX)
+        library [--.lib]freetype_cxx.olb $(OBJS64)
+.endif
 
 # EOF
 $ eod
@@ -1026,6 +2001,7 @@
 $   if cparm .eqs. "DEBUG"
 $   then
 $     ccopt = ccopt + "/noopt/deb"
+$     if x86_64 then cxxopt = cxxopt + "/noopt/deb"
 $     lopts = lopts + "/deb"
 $   endif
 $   if f$locate("CCOPT=",cparm) .lt. f$length(cparm)
@@ -1033,6 +2009,7 @@
 $     start = f$locate("=",cparm) + 1
 $     len   = f$length(cparm) - start
 $     ccopt = ccopt + f$extract(start,len,cparm)
+$     if x86_64 then cxxopt = cxxopt + f$extract(start,len,cparm)
 $   endif
 $   if cparm .eqs. "LINK" then linkonly = true
 $   if f$locate("LOPTS=",cparm) .lt. f$length(cparm)
@@ -1077,230 +2054,4 @@
 $ return
 $!------------------------------------------------------------------------------
 $!
-$! Take care of driver file with information about external libraries
-$!
-$! Version history
-$! 0.01 20040220 First version to receive a number
-$! 0.02 20040229 Echo current procedure name; use general error exit handler
-$!               Remove xpm hack -> Replaced by more general dnsrl handling
-$CHECK_CREATE_VMSLIB:
-$!
-$ if f$search("VMSLIB.DAT") .eqs. ""
-$ then
-$   type/out=vmslib.dat sys$input
-!
-! This is a simple driver file with information used by vms_make.com to
-! check if external libraries (like t1lib and FreeType) are available on
-! the system.
-!
-! Layout of the file:
-!
-!    - Lines starting with ! are treated as comments
-!    - Elements in a data line are separated by # signs
-!    - The elements need to be listed in the following order
-!      1.) Name of the Library (only used for informative messages
-!                               from vms_make.com)
-!      2.) Location where the object library can be found
-!      3.) Location where the include files for the library can be found
-!      4.) Include file used to verify library location
-!      5.) CPP define to pass to the build to indicate availability of
-!          the library
-!
-! Example: The following lines show how definitions
-!          might look like. They are site specific and the locations of the
-!          library and include files need almost certainly to be changed.
-!
-! Location: All of the libraries can be found at the following addresses
-!
-!   ZLIB:     http://zinser.no-ip.info/vms/sw/zlib.htmlx
-!
-ZLIB # sys$library:libz.olb # sys$library: # zlib.h # FT_CONFIG_OPTION_SYSTEM_ZLIB
-$   write sys$output "New driver file vmslib.dat created."
-$   write sys$output "Please customize library locations for your site"
-$   write sys$output "and afterwards re-execute ''myproc'"
-$   goto err_exit
-$ endif
-$!
-$! Init symbols used to hold CPP definitions and include path
-$!
-$ libdefs = "FT2_BUILD_LIBRARY,FT_CONFIG_OPTION_OLD_INTERNALS,"
-$ libincs = ""
-$!
-$! Open data file with location of libraries
-$!
-$ open/read/end=end_lib/err=err_lib libdata VMSLIB.DAT
-$LIB_LOOP:
-$ read/end=end_lib libdata libline
-$ libline = f$edit(libline, "UNCOMMENT,COLLAPSE")
-$ if libline .eqs. "" then goto LIB_LOOP ! Comment line
-$ libname = f$edit(f$element(0,"#",libline),"UPCASE")
-$ write sys$output "Processing ''libname' setup ..."
-$ libloc  = f$element(1,"#",libline)
-$ libsrc  = f$element(2,"#",libline)
-$ testinc = f$element(3,"#",libline)
-$ cppdef  = f$element(4,"#",libline)
-$ old_cpp = f$locate("=1",cppdef)
-$ if old_cpp.lt.f$length(cppdef) then cppdef = f$extract(0,old_cpp,cppdef)
-$ if f$search("''libloc'").eqs. ""
-$ then
-$   write sys$output "Can not find library ''libloc' - Skipping ''libname'"
-$   goto LIB_LOOP
-$ endif
-$ libsrc_elem = 0
-$ libsrc_found = false
-$LIBSRC_LOOP:
-$ libsrcdir = f$element(libsrc_elem,",",libsrc)
-$ if (libsrcdir .eqs. ",") then goto END_LIBSRC
-$ if f$search("''libsrcdir'''testinc'") .nes. "" then libsrc_found = true
-$ libsrc_elem = libsrc_elem + 1
-$ goto LIBSRC_LOOP
-$END_LIBSRC:
-$ if .not. libsrc_found
-$ then
-$   write sys$output "Can not find includes at ''libsrc' - Skipping ''libname'"
-$   goto LIB_LOOP
-$ endif
-$ if (cppdef .nes. "") then libdefs = libdefs +  cppdef + ","
-$ libincs = libincs + "," + libsrc
-$ lqual = "/lib"
-$ libtype = f$edit(f$parse(libloc,,,"TYPE"),"UPCASE")
-$ if f$locate("EXE",libtype) .lt. f$length(libtype) then lqual = "/share"
-$ write optf libloc , lqual
-$ if (f$trnlnm("topt") .nes. "") then write topt libloc , lqual
-$!
-$! Nasty hack to get the FreeType includes to work
-$!
-$ ft2def = false
-$ if ((libname .eqs. "FREETYPE") .and. -
-      (f$locate("FREETYPE2",cppdef) .lt. f$length(cppdef)))
-$ then
-$   if ((f$search("freetype:freetype.h") .nes. "") .and. -
-        (f$search("freetype:[internal]ftobjs.h") .nes. ""))
-$   then
-$     write sys$output "Will use local definition of freetype logical"
-$   else
-$     ft2elem = 0
-$FT2_LOOP:
-$     ft2srcdir = f$element(ft2elem,",",libsrc)
-$     if f$search("''ft2srcdir'''testinc'") .nes. ""
-$     then
-$        if f$search("''ft2srcdir'internal.dir") .nes. ""
-$        then
-$          ft2dev  = f$parse("''ft2srcdir'",,,"device","no_conceal")
-$          ft2dir  = f$parse("''ft2srcdir'",,,"directory","no_conceal")
-$          ft2conc = f$locate("][",ft2dir)
-$          ft2len  = f$length(ft2dir)
-$          if ft2conc .lt. ft2len
-$          then
-$             ft2dir = f$extract(0,ft2conc,ft2dir) + -
-                       f$extract(ft2conc+2,ft2len-2,ft2dir)
-$          endif
-$          ft2dir = ft2dir - "]" + ".]"
-$          define freetype 'ft2dev''ft2dir','ft2srcdir'
-$          ft2def = true
-$        else
-$          goto ft2_err
-$        endif
-$     else
-$       ft2elem = ft2elem + 1
-$       goto ft2_loop
-$     endif
-$   endif
-$ endif
-$ goto LIB_LOOP
-$END_LIB:
-$ close libdata
-$ return
-$!------------------------------------------------------------------------------
-$!
-$! Analyze Object files for OpenVMS AXP to extract Procedure and Data
-$! information to build a symbol vector for a shareable image
-$! All the "brains" of this logic was suggested by Hartmut Becker
-$! (Hartmut.Becker@compaq.com). All the bugs were introduced by me
-$! (zinser@zinser.no-ip.info), so if you do have problem reports please do not
-$! bother Hartmut/HP, but get in touch with me
-$!
-$! Version history
-$! 0.01 20040006 Skip over shareable images in option file
-$!
-$ ANAL_OBJ_AXP: Subroutine
-$ V = 'F$Verify(0)
-$ SAY := "WRITE_ SYS$OUTPUT"
-$
-$ IF F$SEARCH("''P1'") .EQS. ""
-$ THEN
-$    SAY "ANAL_OBJ_AXP-E-NOSUCHFILE:  Error, inputfile ''p1' not available"
-$    goto exit_aa
-$ ENDIF
-$ IF "''P2'" .EQS. ""
-$ THEN
-$    SAY "ANAL_OBJ_AXP:  Error, no output file provided"
-$    goto exit_aa
-$ ENDIF
-$
-$ open/read in 'p1
-$ create a.tmp
-$ open/append atmp a.tmp
-$ loop:
-$ read/end=end_loop in line
-$ if f$locate("/SHARE",f$edit(line,"upcase")) .lt. f$length(line)
-$ then
-$   write sys$output "ANAL_SKP_SHR-i-skipshare, ''line'"
-$   goto loop
-$ endif
-$ if f$locate("/LIB",f$edit(line,"upcase")) .lt. f$length(line)
-$ then
-$   write libsf line
-$   write sys$output "ANAL_SKP_LIB-i-skiplib, ''line'"
-$   goto loop
-$ endif
-$ f= f$search(line)
-$ if f .eqs. ""
-$ then
-$	write sys$output "ANAL_OBJ_AXP-w-nosuchfile, ''line'"
-$	goto loop
-$ endif
-$ def/user sys$output nl:
-$ def/user sys$error nl:
-$ anal/obj/gsd 'f /out=x.tmp
-$ open/read xtmp x.tmp
-$ XLOOP:
-$ read/end=end_xloop xtmp xline
-$ xline = f$edit(xline,"compress")
-$ write atmp xline
-$ goto xloop
-$ END_XLOOP:
-$ close xtmp
-$ goto loop
-$ end_loop:
-$ close in
-$ close atmp
-$ if f$search("a.tmp") .eqs. "" -
-	then $ exit
-$ ! all global definitions
-$ search a.tmp "symbol:","EGSY$V_DEF 1","EGSY$V_NORM 1"/out=b.tmp
-$ ! all procedures
-$ search b.tmp "EGSY$V_NORM 1"/wind=(0,1) /out=c.tmp
-$ search c.tmp "symbol:"/out=d.tmp
-$ def/user sys$output nl:
-$ edito/edt/command=sys$input d.tmp
-sub/symbol: "/symbol_vector=(/whole
-sub/"/=PROCEDURE)/whole
-exit
-$ ! all data
-$ search b.tmp "EGSY$V_DEF 1"/wind=(0,1) /out=e.tmp
-$ search e.tmp "symbol:"/out=f.tmp
-$ def/user sys$output nl:
-$ edito/edt/command=sys$input f.tmp
-sub/symbol: "/symbol_vector=(/whole
-sub/"/=DATA)/whole
-exit
-$ sort/nodupl d.tmp,f.tmp 'p2'
-$ delete a.tmp;*,b.tmp;*,c.tmp;*,d.tmp;*,e.tmp;*,f.tmp;*
-$ if f$search("x.tmp") .nes. "" -
-	then $ delete x.tmp;*
-$!
-$ close libsf
-$ EXIT_AA:
-$ if V then set verify
 $ endsubroutine